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 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 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 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 loop {
69 while self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {} 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 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 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 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 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 self.parse_item_extern_crate()?
232 } else {
233 self.parse_item_foreign_mod(attrs, Safety::Default)?
235 }
236 } else if self.is_unsafe_foreign_mod() {
237 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 self.bump(); 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 self.parse_item_trait(attrs, lo)?
250 } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
251 if self.token.is_keyword(kw::Impl) {
253 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 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 self.parse_item_mod(attrs)?
280 } else if self.eat_keyword(exp!(Type)) {
281 self.parse_type_alias(def_())?
283 } else if self.eat_keyword(exp!(Enum)) {
284 self.parse_item_enum()?
286 } else if self.eat_keyword(exp!(Struct)) {
287 self.parse_item_struct()?
289 } else if self.is_kw_followed_by_ident(kw::Union) {
290 self.bump(); self.parse_item_union()?
293 } else if self.is_builtin() {
294 return self.parse_item_builtin();
296 } else if self.eat_keyword(exp!(Macro)) {
297 self.parse_item_decl_macro(lo)?
299 } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() {
300 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 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 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 pub(super) fn is_path_start_item(&mut self) -> bool {
374 self.is_kw_followed_by_ident(kw::Union) || self.is_reuse_path_item()
376 || self.check_trait_front_matter() || self.is_async_fn() || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) }
380
381 fn is_reuse_path_item(&mut self) -> bool {
382 self.token.is_keyword(kw::Reuse)
384 && self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep)
385 }
386
387 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 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(); }
417
418 let err = if self.check(exp!(OpenBrace)) {
419 if self.look_ahead(1, |t| *t == token::CloseBrace) {
421 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 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 self.bump(); 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(); 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 Ok(None)
477 }
478
479 fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
481 let path = self.parse_path(PathStyle::Mod)?; self.expect(exp!(Bang))?; match self.parse_delim_args() {
484 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 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 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 if self.check(exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) {
543 self.bump(); ast::ImplPolarity::Negative(self.prev_token.span)
545 } else {
546 ast::ImplPolarity::Positive
547 }
548 }
549
550 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 let mut generics = if self.choose_generics_over_qpath(0) {
574 self.parse_generics()?
575 } else {
576 let mut generics = Generics::default();
577 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 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 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 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 self.bump(); 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 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 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 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), };
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 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 && 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 is_unnecessary_semicolon =
787 self.token == token::OpenBrace && self.prev_token == token::Semi;
788 semicolon_span = self.prev_token.span;
789 }
790 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 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 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 fn parse_defaultness(&mut self) -> Defaultness {
862 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(); Defaultness::Default(self.prev_token_uninterpolated_span())
870 } else {
871 Defaultness::Final
872 }
873 }
874
875 fn check_trait_front_matter(&mut self) -> bool {
877 self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait])
879 || 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 fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
887 let constness = self.parse_constness(Case::Sensitive);
888 if let Const::Yes(span) = constness {
889 self.psess.gated_spans.gate(sym::const_trait_impl, span);
890 }
891 let safety = self.parse_safety(Case::Sensitive);
892 let is_auto = if self.eat_keyword(exp!(Auto)) {
894 self.psess.gated_spans.gate(sym::auto_traits, self.prev_token.span);
895 IsAuto::Yes
896 } else {
897 IsAuto::No
898 };
899
900 self.expect_keyword(exp!(Trait))?;
901 let ident = self.parse_ident()?;
902 let mut generics = self.parse_generics()?;
903
904 let had_colon = self.eat(exp!(Colon));
906 let span_at_colon = self.prev_token.span;
907 let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
908
909 let span_before_eq = self.prev_token.span;
910 if self.eat(exp!(Eq)) {
911 if had_colon {
913 let span = span_at_colon.to(span_before_eq);
914 self.dcx().emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
915 }
916
917 let bounds = self.parse_generic_bounds()?;
918 generics.where_clause = self.parse_where_clause()?;
919 self.expect_semi()?;
920
921 let whole_span = lo.to(self.prev_token.span);
922 if let Const::Yes(_) = constness {
923 self.dcx().emit_err(errors::TraitAliasCannotBeConst { span: whole_span });
924 }
925 if is_auto == IsAuto::Yes {
926 self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
927 }
928 if let Safety::Unsafe(_) = safety {
929 self.dcx().emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span });
930 }
931
932 self.psess.gated_spans.gate(sym::trait_alias, whole_span);
933
934 Ok(ItemKind::TraitAlias(ident, generics, bounds))
935 } else {
936 generics.where_clause = self.parse_where_clause()?;
938 let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
939 Ok(ItemKind::Trait(Box::new(Trait {
940 constness,
941 is_auto,
942 safety,
943 ident,
944 generics,
945 bounds,
946 items,
947 })))
948 }
949 }
950
951 pub fn parse_impl_item(
952 &mut self,
953 force_collect: ForceCollect,
954 ) -> PResult<'a, Option<Option<P<AssocItem>>>> {
955 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
956 self.parse_assoc_item(fn_parse_mode, force_collect)
957 }
958
959 pub fn parse_trait_item(
960 &mut self,
961 force_collect: ForceCollect,
962 ) -> PResult<'a, Option<Option<P<AssocItem>>>> {
963 let fn_parse_mode =
964 FnParseMode { req_name: |edition| edition >= Edition::Edition2018, req_body: false };
965 self.parse_assoc_item(fn_parse_mode, force_collect)
966 }
967
968 fn parse_assoc_item(
970 &mut self,
971 fn_parse_mode: FnParseMode,
972 force_collect: ForceCollect,
973 ) -> PResult<'a, Option<Option<P<AssocItem>>>> {
974 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
975 |Item { attrs, id, span, vis, kind, tokens }| {
976 let kind = match AssocItemKind::try_from(kind) {
977 Ok(kind) => kind,
978 Err(kind) => match kind {
979 ItemKind::Static(box StaticItem {
980 ident,
981 ty,
982 safety: _,
983 mutability: _,
984 expr,
985 define_opaque,
986 }) => {
987 self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
988 AssocItemKind::Const(Box::new(ConstItem {
989 defaultness: Defaultness::Final,
990 ident,
991 generics: Generics::default(),
992 ty,
993 expr,
994 define_opaque,
995 }))
996 }
997 _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
998 },
999 };
1000 Some(P(Item { attrs, id, span, vis, kind, tokens }))
1001 },
1002 ))
1003 }
1004
1005 fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
1011 let ident = self.parse_ident()?;
1012 let mut generics = self.parse_generics()?;
1013
1014 let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() };
1016 let before_where_clause = self.parse_where_clause()?;
1017
1018 let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None };
1019
1020 let after_where_clause = self.parse_where_clause()?;
1021
1022 let where_clauses = TyAliasWhereClauses {
1023 before: TyAliasWhereClause {
1024 has_where_token: before_where_clause.has_where_token,
1025 span: before_where_clause.span,
1026 },
1027 after: TyAliasWhereClause {
1028 has_where_token: after_where_clause.has_where_token,
1029 span: after_where_clause.span,
1030 },
1031 split: before_where_clause.predicates.len(),
1032 };
1033 let mut predicates = before_where_clause.predicates;
1034 predicates.extend(after_where_clause.predicates);
1035 let where_clause = WhereClause {
1036 has_where_token: before_where_clause.has_where_token
1037 || after_where_clause.has_where_token,
1038 predicates,
1039 span: DUMMY_SP,
1040 };
1041 generics.where_clause = where_clause;
1042
1043 self.expect_semi()?;
1044
1045 Ok(ItemKind::TyAlias(Box::new(TyAlias {
1046 defaultness,
1047 ident,
1048 generics,
1049 where_clauses,
1050 bounds,
1051 ty,
1052 })))
1053 }
1054
1055 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
1065 let lo = self.token.span;
1066
1067 let mut prefix =
1068 ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo(), tokens: None };
1069 let kind =
1070 if self.check(exp!(OpenBrace)) || self.check(exp!(Star)) || self.is_import_coupler() {
1071 let mod_sep_ctxt = self.token.span.ctxt();
1073 if self.eat_path_sep() {
1074 prefix
1075 .segments
1076 .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
1077 }
1078
1079 self.parse_use_tree_glob_or_nested()?
1080 } else {
1081 prefix = self.parse_path(PathStyle::Mod)?;
1083
1084 if self.eat_path_sep() {
1085 self.parse_use_tree_glob_or_nested()?
1086 } else {
1087 while self.eat_noexpect(&token::Colon) {
1089 self.dcx()
1090 .emit_err(errors::SingleColonImportPath { span: self.prev_token.span });
1091
1092 self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?;
1094 prefix.span = lo.to(self.prev_token.span);
1095 }
1096
1097 UseTreeKind::Simple(self.parse_rename()?)
1098 }
1099 };
1100
1101 Ok(UseTree { prefix, kind, span: lo.to(self.prev_token.span) })
1102 }
1103
1104 fn parse_use_tree_glob_or_nested(&mut self) -> PResult<'a, UseTreeKind> {
1106 Ok(if self.eat(exp!(Star)) {
1107 UseTreeKind::Glob
1108 } else {
1109 let lo = self.token.span;
1110 UseTreeKind::Nested {
1111 items: self.parse_use_tree_list()?,
1112 span: lo.to(self.prev_token.span),
1113 }
1114 })
1115 }
1116
1117 fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> {
1123 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1124 p.recover_vcs_conflict_marker();
1125 Ok((p.parse_use_tree()?, DUMMY_NODE_ID))
1126 })
1127 .map(|(r, _)| r)
1128 }
1129
1130 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
1131 if self.eat_keyword(exp!(As)) {
1132 self.parse_ident_or_underscore().map(Some)
1133 } else {
1134 Ok(None)
1135 }
1136 }
1137
1138 fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
1139 match self.token.ident() {
1140 Some((ident @ Ident { name: kw::Underscore, .. }, IdentIsRaw::No)) => {
1141 self.bump();
1142 Ok(ident)
1143 }
1144 _ => self.parse_ident(),
1145 }
1146 }
1147
1148 fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemKind> {
1157 let orig_ident = self.parse_crate_name_with_dashes()?;
1159 let (orig_name, item_ident) = if let Some(rename) = self.parse_rename()? {
1160 (Some(orig_ident.name), rename)
1161 } else {
1162 (None, orig_ident)
1163 };
1164 self.expect_semi()?;
1165 Ok(ItemKind::ExternCrate(orig_name, item_ident))
1166 }
1167
1168 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
1169 let ident = if self.token.is_keyword(kw::SelfLower) {
1170 self.parse_path_segment_ident()
1171 } else {
1172 self.parse_ident()
1173 }?;
1174
1175 let dash = exp!(Minus);
1176 if self.token != *dash.tok {
1177 return Ok(ident);
1178 }
1179
1180 let mut dashes = vec![];
1182 let mut idents = vec![];
1183 while self.eat(dash) {
1184 dashes.push(self.prev_token.span);
1185 idents.push(self.parse_ident()?);
1186 }
1187
1188 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
1189 let mut fixed_name = ident.name.to_string();
1190 for part in idents {
1191 write!(fixed_name, "_{}", part.name).unwrap();
1192 }
1193
1194 self.dcx().emit_err(errors::ExternCrateNameWithDashes {
1195 span: fixed_name_sp,
1196 sugg: errors::ExternCrateNameWithDashesSugg { dashes },
1197 });
1198
1199 Ok(Ident::from_str_and_span(&fixed_name, fixed_name_sp))
1200 }
1201
1202 fn parse_item_foreign_mod(
1213 &mut self,
1214 attrs: &mut AttrVec,
1215 mut safety: Safety,
1216 ) -> PResult<'a, ItemKind> {
1217 let extern_span = self.prev_token_uninterpolated_span();
1218 let abi = self.parse_abi(); if safety == Safety::Default
1221 && self.token.is_keyword(kw::Unsafe)
1222 && self.look_ahead(1, |t| *t == token::OpenBrace)
1223 {
1224 self.expect(exp!(OpenBrace)).unwrap_err().emit();
1225 safety = Safety::Unsafe(self.token.span);
1226 let _ = self.eat_keyword(exp!(Unsafe));
1227 }
1228 Ok(ItemKind::ForeignMod(ast::ForeignMod {
1229 extern_span,
1230 safety,
1231 abi,
1232 items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
1233 }))
1234 }
1235
1236 pub fn parse_foreign_item(
1238 &mut self,
1239 force_collect: ForceCollect,
1240 ) -> PResult<'a, Option<Option<P<ForeignItem>>>> {
1241 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: false };
1242 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
1243 |Item { attrs, id, span, vis, kind, tokens }| {
1244 let kind = match ForeignItemKind::try_from(kind) {
1245 Ok(kind) => kind,
1246 Err(kind) => match kind {
1247 ItemKind::Const(box ConstItem { ident, ty, expr, .. }) => {
1248 let const_span = Some(span.with_hi(ident.span.lo()))
1249 .filter(|span| span.can_be_used_for_suggestions());
1250 self.dcx().emit_err(errors::ExternItemCannotBeConst {
1251 ident_span: ident.span,
1252 const_span,
1253 });
1254 ForeignItemKind::Static(Box::new(StaticItem {
1255 ident,
1256 ty,
1257 mutability: Mutability::Not,
1258 expr,
1259 safety: Safety::Default,
1260 define_opaque: None,
1261 }))
1262 }
1263 _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
1264 },
1265 };
1266 Some(P(Item { attrs, id, span, vis, kind, tokens }))
1267 },
1268 ))
1269 }
1270
1271 fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
1272 let span = self.psess.source_map().guess_head_span(span);
1274 let descr = kind.descr();
1275 let help = match kind {
1276 ItemKind::DelegationMac(deleg) if deleg.suffixes.is_none() => false,
1277 _ => true,
1278 };
1279 self.dcx().emit_err(errors::BadItemKind { span, descr, ctx, help });
1280 None
1281 }
1282
1283 fn is_use_closure(&self) -> bool {
1284 if self.token.is_keyword(kw::Use) {
1285 self.look_ahead(1, |token| {
1287 let dist =
1289 if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 };
1290
1291 self.look_ahead(dist, |token| matches!(token.kind, token::Or | token::OrOr))
1292 })
1293 } else {
1294 false
1295 }
1296 }
1297
1298 fn is_unsafe_foreign_mod(&self) -> bool {
1299 if !self.token.is_keyword(kw::Unsafe) {
1301 return false;
1302 }
1303 if !self.is_keyword_ahead(1, &[kw::Extern]) {
1305 return false;
1306 }
1307
1308 let n = if self.look_ahead(2, |t| t.can_begin_string_literal()) { 3 } else { 2 };
1310
1311 self.tree_look_ahead(n, |t| matches!(t, TokenTree::Delimited(_, _, Delimiter::Brace, _)))
1316 == Some(true)
1317 }
1318
1319 fn is_static_global(&mut self) -> bool {
1320 if self.check_keyword(exp!(Static)) {
1321 !self.look_ahead(1, |token| {
1323 if token.is_keyword(kw::Move) || token.is_keyword(kw::Use) {
1324 return true;
1325 }
1326 matches!(token.kind, token::Or | token::OrOr)
1327 })
1328 } else {
1329 (self.check_keyword(exp!(Unsafe)) || self.check_keyword(exp!(Safe)))
1331 && self.look_ahead(1, |t| t.is_keyword(kw::Static))
1332 }
1333 }
1334
1335 fn recover_const_mut(&mut self, const_span: Span) {
1337 if self.eat_keyword(exp!(Mut)) {
1338 let span = self.prev_token.span;
1339 self.dcx()
1340 .emit_err(errors::ConstGlobalCannotBeMutable { ident_span: span, const_span });
1341 } else if self.eat_keyword(exp!(Let)) {
1342 let span = self.prev_token.span;
1343 self.dcx().emit_err(errors::ConstLetMutuallyExclusive { span: const_span.to(span) });
1344 }
1345 }
1346
1347 fn recover_const_impl(
1349 &mut self,
1350 const_span: Span,
1351 attrs: &mut AttrVec,
1352 defaultness: Defaultness,
1353 ) -> PResult<'a, ItemKind> {
1354 let impl_span = self.token.span;
1355 let err = self.expected_ident_found_err();
1356
1357 let mut item_kind = match self.parse_item_impl(attrs, defaultness) {
1359 Ok(item_kind) => item_kind,
1360 Err(recovery_error) => {
1361 recovery_error.cancel();
1363 return Err(err);
1364 }
1365 };
1366
1367 match &mut item_kind {
1368 ItemKind::Impl(box Impl { of_trait: Some(trai), constness, .. }) => {
1369 *constness = Const::Yes(const_span);
1370
1371 let before_trait = trai.path.span.shrink_to_lo();
1372 let const_up_to_impl = const_span.with_hi(impl_span.lo());
1373 err.with_multipart_suggestion(
1374 "you might have meant to write a const trait impl",
1375 vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())],
1376 Applicability::MaybeIncorrect,
1377 )
1378 .emit();
1379 }
1380 ItemKind::Impl { .. } => return Err(err),
1381 _ => unreachable!(),
1382 }
1383
1384 Ok(item_kind)
1385 }
1386
1387 fn parse_static_item(
1394 &mut self,
1395 safety: Safety,
1396 mutability: Mutability,
1397 ) -> PResult<'a, ItemKind> {
1398 let ident = self.parse_ident()?;
1399
1400 if self.token == TokenKind::Lt && self.may_recover() {
1401 let generics = self.parse_generics()?;
1402 self.dcx().emit_err(errors::StaticWithGenerics { span: generics.span });
1403 }
1404
1405 let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
1408 (true, false) => self.parse_ty()?,
1409 (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
1412 };
1413
1414 let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1415
1416 self.expect_semi()?;
1417
1418 let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
1419 Ok(ItemKind::Static(Box::new(item)))
1420 }
1421
1422 fn parse_const_item(&mut self) -> PResult<'a, (Ident, Generics, P<Ty>, Option<P<ast::Expr>>)> {
1428 let ident = self.parse_ident_or_underscore()?;
1429
1430 let mut generics = self.parse_generics()?;
1431
1432 if !generics.span.is_empty() {
1435 self.psess.gated_spans.gate(sym::generic_const_items, generics.span);
1436 }
1437
1438 let ty = match (
1441 self.eat(exp!(Colon)),
1442 self.check(exp!(Eq)) | self.check(exp!(Semi)) | self.check_keyword(exp!(Where)),
1443 ) {
1444 (true, false) => self.parse_ty()?,
1445 (colon, _) => self.recover_missing_global_item_type(colon, None),
1447 };
1448
1449 let before_where_clause =
1452 if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() };
1453
1454 let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1455
1456 let after_where_clause = self.parse_where_clause()?;
1457
1458 if before_where_clause.has_where_token
1462 && let Some(expr) = &expr
1463 {
1464 self.dcx().emit_err(errors::WhereClauseBeforeConstBody {
1465 span: before_where_clause.span,
1466 name: ident.span,
1467 body: expr.span,
1468 sugg: if !after_where_clause.has_where_token {
1469 self.psess.source_map().span_to_snippet(expr.span).ok().map(|body| {
1470 errors::WhereClauseBeforeConstBodySugg {
1471 left: before_where_clause.span.shrink_to_lo(),
1472 snippet: body,
1473 right: before_where_clause.span.shrink_to_hi().to(expr.span),
1474 }
1475 })
1476 } else {
1477 None
1480 },
1481 });
1482 }
1483
1484 let mut predicates = before_where_clause.predicates;
1491 predicates.extend(after_where_clause.predicates);
1492 let where_clause = WhereClause {
1493 has_where_token: before_where_clause.has_where_token
1494 || after_where_clause.has_where_token,
1495 predicates,
1496 span: if after_where_clause.has_where_token {
1497 after_where_clause.span
1498 } else {
1499 before_where_clause.span
1500 },
1501 };
1502
1503 if where_clause.has_where_token {
1504 self.psess.gated_spans.gate(sym::generic_const_items, where_clause.span);
1505 }
1506
1507 generics.where_clause = where_clause;
1508
1509 self.expect_semi()?;
1510
1511 Ok((ident, generics, ty, expr))
1512 }
1513
1514 fn recover_missing_global_item_type(
1517 &mut self,
1518 colon_present: bool,
1519 m: Option<Mutability>,
1520 ) -> P<Ty> {
1521 let kind = match m {
1524 Some(Mutability::Mut) => "static mut",
1525 Some(Mutability::Not) => "static",
1526 None => "const",
1527 };
1528
1529 let colon = match colon_present {
1530 true => "",
1531 false => ":",
1532 };
1533
1534 let span = self.prev_token.span.shrink_to_hi();
1535 let err = self.dcx().create_err(errors::MissingConstType { span, colon, kind });
1536 err.stash(span, StashKey::ItemNoType);
1537
1538 P(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
1541 }
1542
1543 fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
1545 if self.token.is_keyword(kw::Struct) {
1546 let span = self.prev_token.span.to(self.token.span);
1547 let err = errors::EnumStructMutuallyExclusive { span };
1548 if self.look_ahead(1, |t| t.is_ident()) {
1549 self.bump();
1550 self.dcx().emit_err(err);
1551 } else {
1552 return Err(self.dcx().create_err(err));
1553 }
1554 }
1555
1556 let prev_span = self.prev_token.span;
1557 let ident = self.parse_ident()?;
1558 let mut generics = self.parse_generics()?;
1559 generics.where_clause = self.parse_where_clause()?;
1560
1561 let (variants, _) = if self.token == TokenKind::Semi {
1563 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
1564 self.bump();
1565 (thin_vec![], Trailing::No)
1566 } else {
1567 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1568 p.parse_enum_variant(ident.span)
1569 })
1570 .map_err(|mut err| {
1571 err.span_label(ident.span, "while parsing this enum");
1572 if self.prev_token.is_non_reserved_ident() && self.token == token::Colon {
1574 let snapshot = self.create_snapshot_for_diagnostic();
1575 self.bump();
1576 match self.parse_ty() {
1577 Ok(_) => {
1578 err.span_suggestion_verbose(
1579 prev_span,
1580 "perhaps you meant to use `struct` here",
1581 "struct",
1582 Applicability::MaybeIncorrect,
1583 );
1584 }
1585 Err(e) => {
1586 e.cancel();
1587 }
1588 }
1589 self.restore_snapshot(snapshot);
1590 }
1591 self.eat_to_tokens(&[exp!(CloseBrace)]);
1592 self.bump(); err
1594 })?
1595 };
1596
1597 let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
1598 Ok(ItemKind::Enum(ident, generics, enum_definition))
1599 }
1600
1601 fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
1602 self.recover_vcs_conflict_marker();
1603 let variant_attrs = self.parse_outer_attributes()?;
1604 self.recover_vcs_conflict_marker();
1605 let help = "enum variants can be `Variant`, `Variant = <integer>`, \
1606 `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`";
1607 self.collect_tokens(None, variant_attrs, ForceCollect::No, |this, variant_attrs| {
1608 let vlo = this.token.span;
1609
1610 let vis = this.parse_visibility(FollowedByType::No)?;
1611 if !this.recover_nested_adt_item(kw::Enum)? {
1612 return Ok((None, Trailing::No, UsePreAttrPos::No));
1613 }
1614 let ident = this.parse_field_ident("enum", vlo)?;
1615
1616 if this.token == token::Bang {
1617 if let Err(err) = this.unexpected() {
1618 err.with_note(fluent::parse_macro_expands_to_enum_variant).emit();
1619 }
1620
1621 this.bump();
1622 this.parse_delim_args()?;
1623
1624 return Ok((None, Trailing::from(this.token == token::Comma), UsePreAttrPos::No));
1625 }
1626
1627 let struct_def = if this.check(exp!(OpenBrace)) {
1628 let (fields, recovered) =
1630 match this.parse_record_struct_body("struct", ident.span, false) {
1631 Ok((fields, recovered)) => (fields, recovered),
1632 Err(mut err) => {
1633 if this.token == token::Colon {
1634 return Err(err);
1636 }
1637 this.eat_to_tokens(&[exp!(CloseBrace)]);
1638 this.bump(); err.span_label(span, "while parsing this enum");
1640 err.help(help);
1641 let guar = err.emit();
1642 (thin_vec![], Recovered::Yes(guar))
1643 }
1644 };
1645 VariantData::Struct { fields, recovered }
1646 } else if this.check(exp!(OpenParen)) {
1647 let body = match this.parse_tuple_struct_body() {
1648 Ok(body) => body,
1649 Err(mut err) => {
1650 if this.token == token::Colon {
1651 return Err(err);
1653 }
1654 this.eat_to_tokens(&[exp!(CloseParen)]);
1655 this.bump(); err.span_label(span, "while parsing this enum");
1657 err.help(help);
1658 err.emit();
1659 thin_vec![]
1660 }
1661 };
1662 VariantData::Tuple(body, DUMMY_NODE_ID)
1663 } else {
1664 VariantData::Unit(DUMMY_NODE_ID)
1665 };
1666
1667 let disr_expr =
1668 if this.eat(exp!(Eq)) { Some(this.parse_expr_anon_const()?) } else { None };
1669
1670 let vr = ast::Variant {
1671 ident,
1672 vis,
1673 id: DUMMY_NODE_ID,
1674 attrs: variant_attrs,
1675 data: struct_def,
1676 disr_expr,
1677 span: vlo.to(this.prev_token.span),
1678 is_placeholder: false,
1679 };
1680
1681 Ok((Some(vr), Trailing::from(this.token == token::Comma), UsePreAttrPos::No))
1682 })
1683 .map_err(|mut err| {
1684 err.help(help);
1685 err
1686 })
1687 }
1688
1689 fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
1691 let ident = self.parse_ident()?;
1692
1693 let mut generics = self.parse_generics()?;
1694
1695 let vdata = if self.token.is_keyword(kw::Where) {
1710 let tuple_struct_body;
1711 (generics.where_clause, tuple_struct_body) =
1712 self.parse_struct_where_clause(ident, generics.span)?;
1713
1714 if let Some(body) = tuple_struct_body {
1715 let body = VariantData::Tuple(body, DUMMY_NODE_ID);
1717 self.expect_semi()?;
1718 body
1719 } else if self.eat(exp!(Semi)) {
1720 VariantData::Unit(DUMMY_NODE_ID)
1722 } else {
1723 let (fields, recovered) = self.parse_record_struct_body(
1725 "struct",
1726 ident.span,
1727 generics.where_clause.has_where_token,
1728 )?;
1729 VariantData::Struct { fields, recovered }
1730 }
1731 } else if self.eat(exp!(Semi)) {
1733 VariantData::Unit(DUMMY_NODE_ID)
1734 } else if self.token == token::OpenBrace {
1736 let (fields, recovered) = self.parse_record_struct_body(
1737 "struct",
1738 ident.span,
1739 generics.where_clause.has_where_token,
1740 )?;
1741 VariantData::Struct { fields, recovered }
1742 } else if self.token == token::OpenParen {
1744 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1745 generics.where_clause = self.parse_where_clause()?;
1746 self.expect_semi()?;
1747 body
1748 } else {
1749 let err = errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token);
1750 return Err(self.dcx().create_err(err));
1751 };
1752
1753 Ok(ItemKind::Struct(ident, generics, vdata))
1754 }
1755
1756 fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
1758 let ident = self.parse_ident()?;
1759
1760 let mut generics = self.parse_generics()?;
1761
1762 let vdata = if self.token.is_keyword(kw::Where) {
1763 generics.where_clause = self.parse_where_clause()?;
1764 let (fields, recovered) = self.parse_record_struct_body(
1765 "union",
1766 ident.span,
1767 generics.where_clause.has_where_token,
1768 )?;
1769 VariantData::Struct { fields, recovered }
1770 } else if self.token == token::OpenBrace {
1771 let (fields, recovered) = self.parse_record_struct_body(
1772 "union",
1773 ident.span,
1774 generics.where_clause.has_where_token,
1775 )?;
1776 VariantData::Struct { fields, recovered }
1777 } else {
1778 let token_str = super::token_descr(&self.token);
1779 let msg = format!("expected `where` or `{{` after union name, found {token_str}");
1780 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1781 err.span_label(self.token.span, "expected `where` or `{` after union name");
1782 return Err(err);
1783 };
1784
1785 Ok(ItemKind::Union(ident, generics, vdata))
1786 }
1787
1788 pub(crate) fn parse_record_struct_body(
1793 &mut self,
1794 adt_ty: &str,
1795 ident_span: Span,
1796 parsed_where: bool,
1797 ) -> PResult<'a, (ThinVec<FieldDef>, Recovered)> {
1798 let mut fields = ThinVec::new();
1799 let mut recovered = Recovered::No;
1800 if self.eat(exp!(OpenBrace)) {
1801 while self.token != token::CloseBrace {
1802 match self.parse_field_def(adt_ty, ident_span) {
1803 Ok(field) => {
1804 fields.push(field);
1805 }
1806 Err(mut err) => {
1807 self.consume_block(
1808 exp!(OpenBrace),
1809 exp!(CloseBrace),
1810 ConsumeClosingDelim::No,
1811 );
1812 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1813 let guar = err.emit();
1814 recovered = Recovered::Yes(guar);
1815 break;
1816 }
1817 }
1818 }
1819 self.expect(exp!(CloseBrace))?;
1820 } else {
1821 let token_str = super::token_descr(&self.token);
1822 let where_str = if parsed_where { "" } else { "`where`, or " };
1823 let msg = format!("expected {where_str}`{{` after struct name, found {token_str}");
1824 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1825 err.span_label(self.token.span, format!("expected {where_str}`{{` after struct name",));
1826 return Err(err);
1827 }
1828
1829 Ok((fields, recovered))
1830 }
1831
1832 fn parse_unsafe_field(&mut self) -> Safety {
1833 if self.eat_keyword(exp!(Unsafe)) {
1835 let span = self.prev_token.span;
1836 self.psess.gated_spans.gate(sym::unsafe_fields, span);
1837 Safety::Unsafe(span)
1838 } else {
1839 Safety::Default
1840 }
1841 }
1842
1843 pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
1844 self.parse_paren_comma_seq(|p| {
1847 let attrs = p.parse_outer_attributes()?;
1848 p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
1849 let mut snapshot = None;
1850 if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
1851 snapshot = Some(p.create_snapshot_for_diagnostic());
1855 }
1856 let lo = p.token.span;
1857 let vis = match p.parse_visibility(FollowedByType::Yes) {
1858 Ok(vis) => vis,
1859 Err(err) => {
1860 if let Some(ref mut snapshot) = snapshot {
1861 snapshot.recover_vcs_conflict_marker();
1862 }
1863 return Err(err);
1864 }
1865 };
1866 let ty = match p.parse_ty() {
1869 Ok(ty) => ty,
1870 Err(err) => {
1871 if let Some(ref mut snapshot) = snapshot {
1872 snapshot.recover_vcs_conflict_marker();
1873 }
1874 return Err(err);
1875 }
1876 };
1877 let mut default = None;
1878 if p.token == token::Eq {
1879 let mut snapshot = p.create_snapshot_for_diagnostic();
1880 snapshot.bump();
1881 match snapshot.parse_expr_anon_const() {
1882 Ok(const_expr) => {
1883 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
1884 p.psess.gated_spans.gate(sym::default_field_values, sp);
1885 p.restore_snapshot(snapshot);
1886 default = Some(const_expr);
1887 }
1888 Err(err) => {
1889 err.cancel();
1890 }
1891 }
1892 }
1893
1894 Ok((
1895 FieldDef {
1896 span: lo.to(ty.span),
1897 vis,
1898 safety: Safety::Default,
1899 ident: None,
1900 id: DUMMY_NODE_ID,
1901 ty,
1902 default,
1903 attrs,
1904 is_placeholder: false,
1905 },
1906 Trailing::from(p.token == token::Comma),
1907 UsePreAttrPos::No,
1908 ))
1909 })
1910 })
1911 .map(|(r, _)| r)
1912 }
1913
1914 fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
1916 self.recover_vcs_conflict_marker();
1917 let attrs = self.parse_outer_attributes()?;
1918 self.recover_vcs_conflict_marker();
1919 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
1920 let lo = this.token.span;
1921 let vis = this.parse_visibility(FollowedByType::No)?;
1922 let safety = this.parse_unsafe_field();
1923 this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
1924 .map(|field| (field, Trailing::No, UsePreAttrPos::No))
1925 })
1926 }
1927
1928 fn parse_single_struct_field(
1930 &mut self,
1931 adt_ty: &str,
1932 lo: Span,
1933 vis: Visibility,
1934 safety: Safety,
1935 attrs: AttrVec,
1936 ident_span: Span,
1937 ) -> PResult<'a, FieldDef> {
1938 let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
1939 match self.token.kind {
1940 token::Comma => {
1941 self.bump();
1942 }
1943 token::Semi => {
1944 self.bump();
1945 let sp = self.prev_token.span;
1946 let mut err =
1947 self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
1948 err.span_suggestion_short(
1949 sp,
1950 "replace `;` with `,`",
1951 ",",
1952 Applicability::MachineApplicable,
1953 );
1954 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1955 err.emit();
1956 }
1957 token::CloseBrace => {}
1958 token::DocComment(..) => {
1959 let previous_span = self.prev_token.span;
1960 let mut err = errors::DocCommentDoesNotDocumentAnything {
1961 span: self.token.span,
1962 missing_comma: None,
1963 };
1964 self.bump(); if self.eat(exp!(Comma)) || self.token == token::CloseBrace {
1966 self.dcx().emit_err(err);
1967 } else {
1968 let sp = previous_span.shrink_to_hi();
1969 err.missing_comma = Some(sp);
1970 return Err(self.dcx().create_err(err));
1971 }
1972 }
1973 _ => {
1974 let sp = self.prev_token.span.shrink_to_hi();
1975 let msg =
1976 format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
1977
1978 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
1980 && let Some(last_segment) = segments.last()
1981 {
1982 let guar = self.check_trailing_angle_brackets(
1983 last_segment,
1984 &[exp!(Comma), exp!(CloseBrace)],
1985 );
1986 if let Some(_guar) = guar {
1987 let _ = self.eat(exp!(Comma));
1990
1991 return Ok(a_var);
1994 }
1995 }
1996
1997 let mut err = self.dcx().struct_span_err(sp, msg);
1998
1999 if self.token.is_ident()
2000 || (self.token == TokenKind::Pound
2001 && (self.look_ahead(1, |t| t == &token::OpenBracket)))
2002 {
2003 err.span_suggestion(
2006 sp,
2007 "try adding a comma",
2008 ",",
2009 Applicability::MachineApplicable,
2010 );
2011 err.emit();
2012 } else {
2013 return Err(err);
2014 }
2015 }
2016 }
2017 Ok(a_var)
2018 }
2019
2020 fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2021 if let Err(err) = self.expect(exp!(Colon)) {
2022 let sm = self.psess.source_map();
2023 let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2024 let semi_typo = self.token == token::Semi
2025 && self.look_ahead(1, |t| {
2026 t.is_path_start()
2027 && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2030 (Ok(l), Ok(r)) => l.line == r.line,
2031 _ => true,
2032 }
2033 });
2034 if eq_typo || semi_typo {
2035 self.bump();
2036 err.with_span_suggestion_short(
2038 self.prev_token.span,
2039 "field names and their types are separated with `:`",
2040 ":",
2041 Applicability::MachineApplicable,
2042 )
2043 .emit();
2044 } else {
2045 return Err(err);
2046 }
2047 }
2048 Ok(())
2049 }
2050
2051 fn parse_name_and_ty(
2053 &mut self,
2054 adt_ty: &str,
2055 lo: Span,
2056 vis: Visibility,
2057 safety: Safety,
2058 attrs: AttrVec,
2059 ) -> PResult<'a, FieldDef> {
2060 let name = self.parse_field_ident(adt_ty, lo)?;
2061 if self.token == token::Bang {
2062 if let Err(mut err) = self.unexpected() {
2063 err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2065 return Err(err);
2066 }
2067 }
2068 self.expect_field_ty_separator()?;
2069 let ty = self.parse_ty()?;
2070 if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2071 self.dcx()
2072 .struct_span_err(self.token.span, "found single colon in a struct field type path")
2073 .with_span_suggestion_verbose(
2074 self.token.span,
2075 "write a path separator here",
2076 "::",
2077 Applicability::MaybeIncorrect,
2078 )
2079 .emit();
2080 }
2081 let default = if self.token == token::Eq {
2082 self.bump();
2083 let const_expr = self.parse_expr_anon_const()?;
2084 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2085 self.psess.gated_spans.gate(sym::default_field_values, sp);
2086 Some(const_expr)
2087 } else {
2088 None
2089 };
2090 Ok(FieldDef {
2091 span: lo.to(self.prev_token.span),
2092 ident: Some(name),
2093 vis,
2094 safety,
2095 id: DUMMY_NODE_ID,
2096 ty,
2097 default,
2098 attrs,
2099 is_placeholder: false,
2100 })
2101 }
2102
2103 fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2106 let (ident, is_raw) = self.ident_or_err(true)?;
2107 if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
2108 let snapshot = self.create_snapshot_for_diagnostic();
2109 let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2110 let inherited_vis =
2111 Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
2112 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
2114 match self.parse_fn(
2115 &mut AttrVec::new(),
2116 fn_parse_mode,
2117 lo,
2118 &inherited_vis,
2119 Case::Insensitive,
2120 ) {
2121 Ok(_) => {
2122 self.dcx().struct_span_err(
2123 lo.to(self.prev_token.span),
2124 format!("functions are not allowed in {adt_ty} definitions"),
2125 )
2126 .with_help(
2127 "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2128 )
2129 .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information")
2130 }
2131 Err(err) => {
2132 err.cancel();
2133 self.restore_snapshot(snapshot);
2134 self.expected_ident_found_err()
2135 }
2136 }
2137 } else if self.eat_keyword(exp!(Struct)) {
2138 match self.parse_item_struct() {
2139 Ok(item) => {
2140 let ItemKind::Struct(ident, ..) = item else { unreachable!() };
2141 self.dcx()
2142 .struct_span_err(
2143 lo.with_hi(ident.span.hi()),
2144 format!("structs are not allowed in {adt_ty} definitions"),
2145 )
2146 .with_help(
2147 "consider creating a new `struct` definition instead of nesting",
2148 )
2149 }
2150 Err(err) => {
2151 err.cancel();
2152 self.restore_snapshot(snapshot);
2153 self.expected_ident_found_err()
2154 }
2155 }
2156 } else {
2157 let mut err = self.expected_ident_found_err();
2158 if self.eat_keyword_noexpect(kw::Let)
2159 && let removal_span = self.prev_token.span.until(self.token.span)
2160 && let Ok(ident) = self
2161 .parse_ident_common(false)
2162 .map_err(|err| err.cancel())
2164 && self.token == TokenKind::Colon
2165 {
2166 err.span_suggestion(
2167 removal_span,
2168 "remove this `let` keyword",
2169 String::new(),
2170 Applicability::MachineApplicable,
2171 );
2172 err.note("the `let` keyword is not allowed in `struct` fields");
2173 err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
2174 err.emit();
2175 return Ok(ident);
2176 } else {
2177 self.restore_snapshot(snapshot);
2178 }
2179 err
2180 };
2181 return Err(err);
2182 }
2183 self.bump();
2184 Ok(ident)
2185 }
2186
2187 fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2195 let ident = self.parse_ident()?;
2196 let body = if self.check(exp!(OpenBrace)) {
2197 self.parse_delim_args()? } else if self.check(exp!(OpenParen)) {
2199 let params = self.parse_token_tree(); let pspan = params.span();
2201 if !self.check(exp!(OpenBrace)) {
2202 self.unexpected()?;
2203 }
2204 let body = self.parse_token_tree(); let bspan = body.span();
2207 let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); let tokens = TokenStream::new(vec![params, arrow, body]);
2209 let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2210 P(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2211 } else {
2212 self.unexpected_any()?
2213 };
2214
2215 self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2216 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false }))
2217 }
2218
2219 fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2221 if self.check_keyword(exp!(MacroRules)) {
2222 let macro_rules_span = self.token.span;
2223
2224 if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2225 return IsMacroRulesItem::Yes { has_bang: true };
2226 } else if self.look_ahead(1, |t| t.is_ident()) {
2227 self.dcx().emit_err(errors::MacroRulesMissingBang {
2229 span: macro_rules_span,
2230 hi: macro_rules_span.shrink_to_hi(),
2231 });
2232
2233 return IsMacroRulesItem::Yes { has_bang: false };
2234 }
2235 }
2236
2237 IsMacroRulesItem::No
2238 }
2239
2240 fn parse_item_macro_rules(
2242 &mut self,
2243 vis: &Visibility,
2244 has_bang: bool,
2245 ) -> PResult<'a, ItemKind> {
2246 self.expect_keyword(exp!(MacroRules))?; if has_bang {
2249 self.expect(exp!(Bang))?; }
2251 let ident = self.parse_ident()?;
2252
2253 if self.eat(exp!(Bang)) {
2254 let span = self.prev_token.span;
2256 self.dcx().emit_err(errors::MacroNameRemoveBang { span });
2257 }
2258
2259 let body = self.parse_delim_args()?;
2260 self.eat_semi_for_macro_if_needed(&body);
2261 self.complain_if_pub_macro(vis, true);
2262
2263 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true }))
2264 }
2265
2266 fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
2269 if let VisibilityKind::Inherited = vis.kind {
2270 return;
2271 }
2272
2273 let vstr = pprust::vis_to_string(vis);
2274 let vstr = vstr.trim_end();
2275 if macro_rules {
2276 self.dcx().emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
2277 } else {
2278 self.dcx().emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
2279 }
2280 }
2281
2282 fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) {
2283 if args.need_semicolon() && !self.eat(exp!(Semi)) {
2284 self.report_invalid_macro_expansion_item(args);
2285 }
2286 }
2287
2288 fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) {
2289 let span = args.dspan.entire();
2290 let mut err = self.dcx().struct_span_err(
2291 span,
2292 "macros that expand to items must be delimited with braces or followed by a semicolon",
2293 );
2294 if !span.from_expansion() {
2297 let DelimSpan { open, close } = args.dspan;
2298 err.multipart_suggestion(
2299 "change the delimiters to curly braces",
2300 vec![(open, "{".to_string()), (close, '}'.to_string())],
2301 Applicability::MaybeIncorrect,
2302 );
2303 err.span_suggestion(
2304 span.with_neighbor(self.token.span).shrink_to_hi(),
2305 "add a semicolon",
2306 ';',
2307 Applicability::MaybeIncorrect,
2308 );
2309 }
2310 err.emit();
2311 }
2312
2313 fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
2316 if (self.token.is_keyword(kw::Enum)
2317 || self.token.is_keyword(kw::Struct)
2318 || self.token.is_keyword(kw::Union))
2319 && self.look_ahead(1, |t| t.is_ident())
2320 {
2321 let kw_token = self.token;
2322 let kw_str = pprust::token_to_string(&kw_token);
2323 let item = self.parse_item(ForceCollect::No)?;
2324 let mut item = item.unwrap().span;
2325 if self.token == token::Comma {
2326 item = item.to(self.token.span);
2327 }
2328 self.dcx().emit_err(errors::NestedAdt {
2329 span: kw_token.span,
2330 item,
2331 kw_str,
2332 keyword: keyword.as_str(),
2333 });
2334 return Ok(false);
2336 }
2337 Ok(true)
2338 }
2339}
2340
2341type ReqName = fn(Edition) -> bool;
2348
2349#[derive(Clone, Copy)]
2357pub(crate) struct FnParseMode {
2358 pub(super) req_name: ReqName,
2381 pub(super) req_body: bool,
2400}
2401
2402impl<'a> Parser<'a> {
2404 fn parse_fn(
2406 &mut self,
2407 attrs: &mut AttrVec,
2408 fn_parse_mode: FnParseMode,
2409 sig_lo: Span,
2410 vis: &Visibility,
2411 case: Case,
2412 ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<FnContract>>, Option<P<Block>>)> {
2413 let fn_span = self.token.span;
2414 let header = self.parse_fn_front_matter(vis, case, FrontMatterParsingMode::Function)?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; let decl = match self.parse_fn_decl(
2418 fn_parse_mode.req_name,
2419 AllowPlus::Yes,
2420 RecoverReturnSign::Yes,
2421 ) {
2422 Ok(decl) => decl,
2423 Err(old_err) => {
2424 if self.token.is_keyword(kw::For) {
2426 old_err.cancel();
2427 return Err(self.dcx().create_err(errors::FnTypoWithImpl { fn_span }));
2428 } else {
2429 return Err(old_err);
2430 }
2431 }
2432 };
2433
2434 let fn_params_end = self.prev_token.span.shrink_to_hi();
2437
2438 let contract = self.parse_contract()?;
2439
2440 generics.where_clause = self.parse_where_clause()?; let fn_params_end =
2444 if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2445
2446 let mut sig_hi = self.prev_token.span;
2447 let body =
2449 self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
2450 let fn_sig_span = sig_lo.to(sig_hi);
2451 Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
2452 }
2453
2454 fn error_fn_body_not_found(
2456 &mut self,
2457 ident_span: Span,
2458 req_body: bool,
2459 fn_params_end: Option<Span>,
2460 ) -> PResult<'a, ErrorGuaranteed> {
2461 let expected: &[_] =
2462 if req_body { &[exp!(OpenBrace)] } else { &[exp!(Semi), exp!(OpenBrace)] };
2463 match self.expected_one_of_not_found(&[], expected) {
2464 Ok(error_guaranteed) => Ok(error_guaranteed),
2465 Err(mut err) => {
2466 if self.token == token::CloseBrace {
2467 err.span_label(ident_span, "while parsing this `fn`");
2470 Ok(err.emit())
2471 } else if self.token == token::RArrow
2472 && let Some(fn_params_end) = fn_params_end
2473 {
2474 let fn_trait_span =
2480 [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2481 if self.prev_token.is_ident_named(symbol) {
2482 Some(self.prev_token.span)
2483 } else {
2484 None
2485 }
2486 });
2487
2488 let arrow_span = self.token.span;
2493 let ty_span = match self.parse_ret_ty(
2494 AllowPlus::Yes,
2495 RecoverQPath::Yes,
2496 RecoverReturnSign::Yes,
2497 ) {
2498 Ok(ty_span) => ty_span.span().shrink_to_hi(),
2499 Err(parse_error) => {
2500 parse_error.cancel();
2501 return Err(err);
2502 }
2503 };
2504 let ret_ty_span = arrow_span.to(ty_span);
2505
2506 if let Some(fn_trait_span) = fn_trait_span {
2507 err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2510 } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2511 {
2512 err.primary_message(
2516 "return type should be specified after the function parameters",
2517 );
2518 err.subdiagnostic(errors::MisplacedReturnType {
2519 fn_params_end,
2520 snippet,
2521 ret_ty_span,
2522 });
2523 }
2524 Err(err)
2525 } else {
2526 Err(err)
2527 }
2528 }
2529 }
2530 }
2531
2532 fn parse_fn_body(
2536 &mut self,
2537 attrs: &mut AttrVec,
2538 ident: &Ident,
2539 sig_hi: &mut Span,
2540 req_body: bool,
2541 fn_params_end: Option<Span>,
2542 ) -> PResult<'a, Option<P<Block>>> {
2543 let has_semi = if req_body {
2544 self.token == TokenKind::Semi
2545 } else {
2546 self.check(exp!(Semi))
2548 };
2549 let (inner_attrs, body) = if has_semi {
2550 self.expect_semi()?;
2552 *sig_hi = self.prev_token.span;
2553 (AttrVec::new(), None)
2554 } else if self.check(exp!(OpenBrace)) || self.token.is_metavar_block() {
2555 self.parse_block_common(self.token.span, BlockCheckMode::Default, None)
2556 .map(|(attrs, body)| (attrs, Some(body)))?
2557 } else if self.token == token::Eq {
2558 self.bump(); let eq_sp = self.prev_token.span;
2561 let _ = self.parse_expr()?;
2562 self.expect_semi()?; let span = eq_sp.to(self.prev_token.span);
2564 let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
2565 span,
2566 sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
2567 });
2568 (AttrVec::new(), Some(self.mk_block_err(span, guar)))
2569 } else {
2570 self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
2571 (AttrVec::new(), None)
2572 };
2573 attrs.extend(inner_attrs);
2574 Ok(body)
2575 }
2576
2577 pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
2582 const ALL_QUALS: &[ExpKeywordPair] = &[
2583 exp!(Pub),
2584 exp!(Gen),
2585 exp!(Const),
2586 exp!(Async),
2587 exp!(Unsafe),
2588 exp!(Safe),
2589 exp!(Extern),
2590 ];
2591
2592 let quals: &[_] = if check_pub {
2597 ALL_QUALS
2598 } else {
2599 &[exp!(Gen), exp!(Const), exp!(Async), exp!(Unsafe), exp!(Safe), exp!(Extern)]
2600 };
2601 self.check_keyword_case(exp!(Fn), case) || quals.iter().any(|&exp| self.check_keyword_case(exp, case))
2604 && self.look_ahead(1, |t| {
2605 t.is_keyword_case(kw::Fn, case)
2607 || (
2609 (
2610 t.is_non_raw_ident_where(|i|
2611 quals.iter().any(|exp| exp.kw == i.name)
2612 && i.is_reserved()
2614 )
2615 || case == Case::Insensitive
2616 && t.is_non_raw_ident_where(|i| quals.iter().any(|exp| {
2617 exp.kw.as_str() == i.name.as_str().to_lowercase()
2618 }))
2619 )
2620 && !self.is_unsafe_foreign_mod()
2622 && !self.is_async_gen_block())
2624 })
2625 || self.check_keyword_case(exp!(Extern), case)
2627 && self.look_ahead(1, |t| t.can_begin_string_literal())
2631 && (self.tree_look_ahead(2, |tt| {
2632 match tt {
2633 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2634 TokenTree::Delimited(..) => false,
2635 }
2636 }) == Some(true) ||
2637 (self.may_recover()
2640 && self.tree_look_ahead(2, |tt| {
2641 match tt {
2642 TokenTree::Token(t, _) =>
2643 ALL_QUALS.iter().any(|exp| {
2644 t.is_keyword(exp.kw)
2645 }),
2646 TokenTree::Delimited(..) => false,
2647 }
2648 }) == Some(true)
2649 && self.tree_look_ahead(3, |tt| {
2650 match tt {
2651 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2652 TokenTree::Delimited(..) => false,
2653 }
2654 }) == Some(true)
2655 )
2656 )
2657 }
2658
2659 pub(super) fn parse_fn_front_matter(
2674 &mut self,
2675 orig_vis: &Visibility,
2676 case: Case,
2677 parsing_mode: FrontMatterParsingMode,
2678 ) -> PResult<'a, FnHeader> {
2679 let sp_start = self.token.span;
2680 let constness = self.parse_constness(case);
2681 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2682 && let Const::Yes(const_span) = constness
2683 {
2684 self.dcx().emit_err(FnPointerCannotBeConst {
2685 span: const_span,
2686 suggestion: const_span.until(self.token.span),
2687 });
2688 }
2689
2690 let async_start_sp = self.token.span;
2691 let coroutine_kind = self.parse_coroutine_kind(case);
2692 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2693 && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind
2694 {
2695 self.dcx().emit_err(FnPointerCannotBeAsync {
2696 span: async_span,
2697 suggestion: async_span.until(self.token.span),
2698 });
2699 }
2700 let unsafe_start_sp = self.token.span;
2703 let safety = self.parse_safety(case);
2704
2705 let ext_start_sp = self.token.span;
2706 let ext = self.parse_extern(case);
2707
2708 if let Some(CoroutineKind::Async { span, .. }) = coroutine_kind {
2709 if span.is_rust_2015() {
2710 self.dcx().emit_err(errors::AsyncFnIn2015 {
2711 span,
2712 help: errors::HelpUseLatestEdition::new(),
2713 });
2714 }
2715 }
2716
2717 match coroutine_kind {
2718 Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
2719 self.psess.gated_spans.gate(sym::gen_blocks, span);
2720 }
2721 Some(CoroutineKind::Async { .. }) | None => {}
2722 }
2723
2724 if !self.eat_keyword_case(exp!(Fn), case) {
2725 match self.expect_one_of(&[], &[]) {
2729 Ok(Recovered::Yes(_)) => {}
2730 Ok(Recovered::No) => unreachable!(),
2731 Err(mut err) => {
2732 enum WrongKw {
2734 Duplicated(Span),
2735 Misplaced(Span),
2736 MisplacedDisallowedQualifier,
2741 }
2742
2743 let mut recover_constness = constness;
2745 let mut recover_coroutine_kind = coroutine_kind;
2746 let mut recover_safety = safety;
2747 let wrong_kw = if self.check_keyword(exp!(Const)) {
2750 match constness {
2751 Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
2752 Const::No => {
2753 recover_constness = Const::Yes(self.token.span);
2754 match parsing_mode {
2755 FrontMatterParsingMode::Function => {
2756 Some(WrongKw::Misplaced(async_start_sp))
2757 }
2758 FrontMatterParsingMode::FunctionPtrType => {
2759 self.dcx().emit_err(FnPointerCannotBeConst {
2760 span: self.token.span,
2761 suggestion: self
2762 .token
2763 .span
2764 .with_lo(self.prev_token.span.hi()),
2765 });
2766 Some(WrongKw::MisplacedDisallowedQualifier)
2767 }
2768 }
2769 }
2770 }
2771 } else if self.check_keyword(exp!(Async)) {
2772 match coroutine_kind {
2773 Some(CoroutineKind::Async { span, .. }) => {
2774 Some(WrongKw::Duplicated(span))
2775 }
2776 Some(CoroutineKind::AsyncGen { span, .. }) => {
2777 Some(WrongKw::Duplicated(span))
2778 }
2779 Some(CoroutineKind::Gen { .. }) => {
2780 recover_coroutine_kind = Some(CoroutineKind::AsyncGen {
2781 span: self.token.span,
2782 closure_id: DUMMY_NODE_ID,
2783 return_impl_trait_id: DUMMY_NODE_ID,
2784 });
2785 Some(WrongKw::Misplaced(unsafe_start_sp))
2787 }
2788 None => {
2789 recover_coroutine_kind = Some(CoroutineKind::Async {
2790 span: self.token.span,
2791 closure_id: DUMMY_NODE_ID,
2792 return_impl_trait_id: DUMMY_NODE_ID,
2793 });
2794 match parsing_mode {
2795 FrontMatterParsingMode::Function => {
2796 Some(WrongKw::Misplaced(async_start_sp))
2797 }
2798 FrontMatterParsingMode::FunctionPtrType => {
2799 self.dcx().emit_err(FnPointerCannotBeAsync {
2800 span: self.token.span,
2801 suggestion: self
2802 .token
2803 .span
2804 .with_lo(self.prev_token.span.hi()),
2805 });
2806 Some(WrongKw::MisplacedDisallowedQualifier)
2807 }
2808 }
2809 }
2810 }
2811 } else if self.check_keyword(exp!(Unsafe)) {
2812 match safety {
2813 Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
2814 Safety::Safe(sp) => {
2815 recover_safety = Safety::Unsafe(self.token.span);
2816 Some(WrongKw::Misplaced(sp))
2817 }
2818 Safety::Default => {
2819 recover_safety = Safety::Unsafe(self.token.span);
2820 Some(WrongKw::Misplaced(ext_start_sp))
2821 }
2822 }
2823 } else if self.check_keyword(exp!(Safe)) {
2824 match safety {
2825 Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
2826 Safety::Unsafe(sp) => {
2827 recover_safety = Safety::Safe(self.token.span);
2828 Some(WrongKw::Misplaced(sp))
2829 }
2830 Safety::Default => {
2831 recover_safety = Safety::Safe(self.token.span);
2832 Some(WrongKw::Misplaced(ext_start_sp))
2833 }
2834 }
2835 } else {
2836 None
2837 };
2838
2839 if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw {
2841 let original_kw = self
2842 .span_to_snippet(original_sp)
2843 .expect("Span extracted directly from keyword should always work");
2844
2845 err.span_suggestion(
2846 self.token_uninterpolated_span(),
2847 format!("`{original_kw}` already used earlier, remove this one"),
2848 "",
2849 Applicability::MachineApplicable,
2850 )
2851 .span_note(original_sp, format!("`{original_kw}` first seen here"));
2852 }
2853 else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
2855 let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
2856 if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
2857 let misplaced_qual_sp = self.token_uninterpolated_span();
2858 let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
2859
2860 err.span_suggestion(
2861 correct_pos_sp.to(misplaced_qual_sp),
2862 format!("`{misplaced_qual}` must come before `{current_qual}`"),
2863 format!("{misplaced_qual} {current_qual}"),
2864 Applicability::MachineApplicable,
2865 ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
2866 }
2867 }
2868 else if self.check_keyword(exp!(Pub)) {
2870 let sp = sp_start.to(self.prev_token.span);
2871 if let Ok(snippet) = self.span_to_snippet(sp) {
2872 let current_vis = match self.parse_visibility(FollowedByType::No) {
2873 Ok(v) => v,
2874 Err(d) => {
2875 d.cancel();
2876 return Err(err);
2877 }
2878 };
2879 let vs = pprust::vis_to_string(¤t_vis);
2880 let vs = vs.trim_end();
2881
2882 if matches!(orig_vis.kind, VisibilityKind::Inherited) {
2884 err.span_suggestion(
2885 sp_start.to(self.prev_token.span),
2886 format!("visibility `{vs}` must come before `{snippet}`"),
2887 format!("{vs} {snippet}"),
2888 Applicability::MachineApplicable,
2889 );
2890 }
2891 else {
2893 err.span_suggestion(
2894 current_vis.span,
2895 "there is already a visibility modifier, remove one",
2896 "",
2897 Applicability::MachineApplicable,
2898 )
2899 .span_note(orig_vis.span, "explicit visibility first seen here");
2900 }
2901 }
2902 }
2903
2904 if let Some(wrong_kw) = wrong_kw
2907 && self.may_recover()
2908 && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
2909 {
2910 self.bump();
2912 self.bump();
2913 if matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) {
2916 err.cancel();
2917 } else {
2918 err.emit();
2919 }
2920 return Ok(FnHeader {
2921 constness: recover_constness,
2922 safety: recover_safety,
2923 coroutine_kind: recover_coroutine_kind,
2924 ext,
2925 });
2926 }
2927
2928 return Err(err);
2929 }
2930 }
2931 }
2932
2933 Ok(FnHeader { constness, safety, coroutine_kind, ext })
2934 }
2935
2936 pub(super) fn parse_fn_decl(
2938 &mut self,
2939 req_name: ReqName,
2940 ret_allow_plus: AllowPlus,
2941 recover_return_sign: RecoverReturnSign,
2942 ) -> PResult<'a, P<FnDecl>> {
2943 Ok(P(FnDecl {
2944 inputs: self.parse_fn_params(req_name)?,
2945 output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
2946 }))
2947 }
2948
2949 pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinVec<Param>> {
2951 let mut first_param = true;
2952 if self.token != TokenKind::OpenParen
2954 && !self.token.is_keyword(kw::For)
2956 {
2957 self.dcx()
2959 .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() });
2960 return Ok(ThinVec::new());
2961 }
2962
2963 let (mut params, _) = self.parse_paren_comma_seq(|p| {
2964 p.recover_vcs_conflict_marker();
2965 let snapshot = p.create_snapshot_for_diagnostic();
2966 let param = p.parse_param_general(req_name, first_param, true).or_else(|e| {
2967 let guar = e.emit();
2968 let lo = if let TokenKind::OpenParen = p.prev_token.kind {
2972 p.prev_token.span.shrink_to_hi()
2973 } else {
2974 p.prev_token.span
2975 };
2976 p.restore_snapshot(snapshot);
2977 p.eat_to_tokens(&[exp!(Comma), exp!(CloseParen)]);
2979 Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
2981 });
2982 first_param = false;
2984 param
2985 })?;
2986 self.deduplicate_recovered_params_names(&mut params);
2988 Ok(params)
2989 }
2990
2991 pub(super) fn parse_param_general(
2996 &mut self,
2997 req_name: ReqName,
2998 first_param: bool,
2999 recover_arg_parse: bool,
3000 ) -> PResult<'a, Param> {
3001 let lo = self.token.span;
3002 let attrs = self.parse_outer_attributes()?;
3003 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
3004 if let Some(mut param) = this.parse_self_param()? {
3006 param.attrs = attrs;
3007 let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
3008 return Ok((res?, Trailing::No, UsePreAttrPos::No));
3009 }
3010
3011 let is_name_required = match this.token.kind {
3012 token::DotDotDot => false,
3013 _ => req_name(this.token.span.with_neighbor(this.prev_token.span).edition()),
3014 };
3015 let (pat, ty) = if is_name_required || this.is_named_param() {
3016 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
3017 let (pat, colon) = this.parse_fn_param_pat_colon()?;
3018 if !colon {
3019 let mut err = this.unexpected().unwrap_err();
3020 return if let Some(ident) =
3021 this.parameter_without_type(&mut err, pat, is_name_required, first_param)
3022 {
3023 let guar = err.emit();
3024 Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No))
3025 } else {
3026 Err(err)
3027 };
3028 }
3029
3030 this.eat_incorrect_doc_comment_for_param_type();
3031 (pat, this.parse_ty_for_param()?)
3032 } else {
3033 debug!("parse_param_general ident_to_pat");
3034 let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
3035 this.eat_incorrect_doc_comment_for_param_type();
3036 let mut ty = this.parse_ty_for_param();
3037
3038 if let Ok(t) = &ty {
3039 if let TyKind::Path(_, Path { segments, .. }) = &t.kind
3041 && let Some(segment) = segments.last()
3042 && let Some(guar) =
3043 this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
3044 {
3045 return Ok((
3046 dummy_arg(segment.ident, guar),
3047 Trailing::No,
3048 UsePreAttrPos::No,
3049 ));
3050 }
3051
3052 if this.token != token::Comma && this.token != token::CloseParen {
3053 ty = this.unexpected_any();
3056 }
3057 }
3058 match ty {
3059 Ok(ty) => {
3060 let pat = this.mk_pat(ty.span, PatKind::Missing);
3061 (pat, ty)
3062 }
3063 Err(err) if this.token == token::DotDotDot => return Err(err),
3065 Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
3066 Err(err) if recover_arg_parse => {
3067 err.cancel();
3069 this.restore_snapshot(parser_snapshot_before_ty);
3070 this.recover_arg_parse()?
3071 }
3072 Err(err) => return Err(err),
3073 }
3074 };
3075
3076 let span = lo.to(this.prev_token.span);
3077
3078 Ok((
3079 Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
3080 Trailing::No,
3081 UsePreAttrPos::No,
3082 ))
3083 })
3084 }
3085
3086 fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
3088 let expect_self_ident = |this: &mut Self| match this.token.ident() {
3090 Some((ident, IdentIsRaw::No)) => {
3091 this.bump();
3092 ident
3093 }
3094 _ => unreachable!(),
3095 };
3096 let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
3098 let is_isolated_self = |this: &Self, n| {
3100 this.is_keyword_ahead(n, &[kw::SelfLower])
3101 && this.look_ahead(n + 1, |t| t != &token::PathSep)
3102 };
3103 let is_isolated_pin_const_self = |this: &Self, n| {
3105 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3106 && this.is_keyword_ahead(n + 1, &[kw::Const])
3107 && is_isolated_self(this, n + 2)
3108 };
3109 let is_isolated_mut_self =
3111 |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
3112 let is_isolated_pin_mut_self = |this: &Self, n| {
3114 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3115 && is_isolated_mut_self(this, n + 1)
3116 };
3117 let parse_self_possibly_typed = |this: &mut Self, m| {
3119 let eself_ident = expect_self_ident(this);
3120 let eself_hi = this.prev_token.span;
3121 let eself = if this.eat(exp!(Colon)) {
3122 SelfKind::Explicit(this.parse_ty()?, m)
3123 } else {
3124 SelfKind::Value(m)
3125 };
3126 Ok((eself, eself_ident, eself_hi))
3127 };
3128 let expect_self_ident_not_typed =
3129 |this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
3130 let eself_ident = expect_self_ident(this);
3131
3132 if this.may_recover() && this.eat_noexpect(&token::Colon) {
3134 let snap = this.create_snapshot_for_diagnostic();
3135 match this.parse_ty() {
3136 Ok(ty) => {
3137 this.dcx().emit_err(errors::IncorrectTypeOnSelf {
3138 span: ty.span,
3139 move_self_modifier: errors::MoveSelfModifier {
3140 removal_span: modifier_span,
3141 insertion_span: ty.span.shrink_to_lo(),
3142 modifier: modifier.to_ref_suggestion(),
3143 },
3144 });
3145 }
3146 Err(diag) => {
3147 diag.cancel();
3148 this.restore_snapshot(snap);
3149 }
3150 }
3151 }
3152 eself_ident
3153 };
3154 let recover_self_ptr = |this: &mut Self| {
3156 this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
3157
3158 Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
3159 };
3160
3161 let eself_lo = self.token.span;
3165 let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
3166 token::And => {
3167 let has_lifetime = is_lifetime(self, 1);
3168 let skip_lifetime_count = has_lifetime as usize;
3169 let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3170 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3173 SelfKind::Region(lifetime, Mutability::Not)
3174 } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3175 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3178 self.bump(); SelfKind::Region(lifetime, Mutability::Mut)
3180 } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3181 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3184 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3185 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Not)
3188 } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
3189 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3192 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3193 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Mut)
3196 } else {
3197 return Ok(None);
3199 };
3200 let hi = self.token.span;
3201 let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3202 (eself, self_ident, hi)
3203 }
3204 token::Star if is_isolated_self(self, 1) => {
3206 self.bump();
3207 recover_self_ptr(self)?
3208 }
3209 token::Star
3211 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
3212 {
3213 self.bump();
3214 self.bump();
3215 recover_self_ptr(self)?
3216 }
3217 token::Ident(..) if is_isolated_self(self, 0) => {
3219 parse_self_possibly_typed(self, Mutability::Not)?
3220 }
3221 token::Ident(..) if is_isolated_mut_self(self, 0) => {
3223 self.bump();
3224 parse_self_possibly_typed(self, Mutability::Mut)?
3225 }
3226 _ => return Ok(None),
3227 };
3228
3229 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
3230 Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
3231 }
3232
3233 fn is_named_param(&self) -> bool {
3234 let offset = match &self.token.kind {
3235 token::OpenInvisible(origin) => match origin {
3236 InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
3237 return self.check_noexpect_past_close_delim(&token::Colon);
3238 }
3239 _ => 0,
3240 },
3241 token::And | token::AndAnd => 1,
3242 _ if self.token.is_keyword(kw::Mut) => 1,
3243 _ => 0,
3244 };
3245
3246 self.look_ahead(offset, |t| t.is_ident())
3247 && self.look_ahead(offset + 1, |t| t == &token::Colon)
3248 }
3249
3250 fn recover_self_param(&mut self) -> bool {
3251 matches!(
3252 self.parse_outer_attributes()
3253 .and_then(|_| self.parse_self_param())
3254 .map_err(|e| e.cancel()),
3255 Ok(Some(_))
3256 )
3257 }
3258}
3259
3260enum IsMacroRulesItem {
3261 Yes { has_bang: bool },
3262 No,
3263}
3264
3265#[derive(Copy, Clone, PartialEq, Eq)]
3266pub(super) enum FrontMatterParsingMode {
3267 Function,
3269 FunctionPtrType,
3272}