1use std::fmt::Write;
2use std::mem;
3
4use ast::token::IdentIsRaw;
5use rustc_ast::ast::*;
6use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind};
7use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
8use rustc_ast::util::case::Case;
9use rustc_ast::{
10 attr, {self as ast},
11};
12use rustc_ast_pretty::pprust;
13use rustc_errors::codes::*;
14use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err};
15use rustc_session::lint::builtin::VARARGS_WITHOUT_PATTERN;
16use rustc_span::edit_distance::edit_distance;
17use rustc_span::edition::Edition;
18use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, source_map, sym};
19use thin_vec::{ThinVec, thin_vec};
20use tracing::debug;
21
22use super::diagnostics::{ConsumeClosingDelim, dummy_arg};
23use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
24use super::{
25 AttrWrapper, ExpKeywordPair, ExpTokenPair, FollowedByType, ForceCollect, Parser, PathStyle,
26 Recovered, Trailing, UsePreAttrPos,
27};
28use crate::errors::{self, FnPointerCannotBeAsync, FnPointerCannotBeConst, MacroExpandsToAdtField};
29use crate::{exp, fluent_generated as fluent};
30
31impl<'a> Parser<'a> {
32 pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> {
34 let (attrs, items, spans) = self.parse_mod(exp!(Eof))?;
35 Ok(ast::Crate { attrs, items, spans, id: DUMMY_NODE_ID, is_placeholder: false })
36 }
37
38 fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemKind> {
40 let safety = self.parse_safety(Case::Sensitive);
41 self.expect_keyword(exp!(Mod))?;
42 let ident = self.parse_ident()?;
43 let mod_kind = if self.eat(exp!(Semi)) {
44 ModKind::Unloaded
45 } else {
46 self.expect(exp!(OpenBrace))?;
47 let (inner_attrs, items, inner_span) = self.parse_mod(exp!(CloseBrace))?;
48 attrs.extend(inner_attrs);
49 ModKind::Loaded(items, Inline::Yes, inner_span)
50 };
51 Ok(ItemKind::Mod(safety, ident, mod_kind))
52 }
53
54 pub fn parse_mod(
59 &mut self,
60 term: ExpTokenPair,
61 ) -> PResult<'a, (AttrVec, ThinVec<Box<Item>>, ModSpans)> {
62 let lo = self.token.span;
63 let attrs = self.parse_inner_attributes()?;
64
65 let post_attr_lo = self.token.span;
66 let mut items: ThinVec<Box<_>> = ThinVec::new();
67
68 loop {
71 while self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {} let Some(item) = self.parse_item(ForceCollect::No)? else {
73 break;
74 };
75 items.push(item);
76 }
77
78 if !self.eat(term) {
79 let token_str = super::token_descr(&self.token);
80 if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {
81 let is_let = self.token.is_keyword(kw::Let);
82 let is_let_mut = is_let && self.look_ahead(1, |t| t.is_keyword(kw::Mut));
83 let let_has_ident = is_let && !is_let_mut && self.is_kw_followed_by_ident(kw::Let);
84
85 let msg = format!("expected item, found {token_str}");
86 let mut err = self.dcx().struct_span_err(self.token.span, msg);
87
88 let label = if is_let {
89 "`let` cannot be used for global variables"
90 } else {
91 "expected item"
92 };
93 err.span_label(self.token.span, label);
94
95 if is_let {
96 if is_let_mut {
97 err.help("consider using `static` and a `Mutex` instead of `let mut`");
98 } else if let_has_ident {
99 err.span_suggestion_short(
100 self.token.span,
101 "consider using `static` or `const` instead of `let`",
102 "static",
103 Applicability::MaybeIncorrect,
104 );
105 } else {
106 err.help("consider using `static` or `const` instead of `let`");
107 }
108 }
109 err.note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");
110 return Err(err);
111 }
112 }
113
114 let inject_use_span = post_attr_lo.data().with_hi(post_attr_lo.lo());
115 let mod_spans = ModSpans { inner_span: lo.to(self.prev_token.span), inject_use_span };
116 Ok((attrs, items, mod_spans))
117 }
118}
119
120impl<'a> Parser<'a> {
121 pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Box<Item>>> {
122 let fn_parse_mode =
123 FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
124 self.parse_item_(fn_parse_mode, force_collect).map(|i| i.map(Box::new))
125 }
126
127 fn parse_item_(
128 &mut self,
129 fn_parse_mode: FnParseMode,
130 force_collect: ForceCollect,
131 ) -> PResult<'a, Option<Item>> {
132 self.recover_vcs_conflict_marker();
133 let attrs = self.parse_outer_attributes()?;
134 self.recover_vcs_conflict_marker();
135 self.parse_item_common(attrs, true, false, fn_parse_mode, force_collect)
136 }
137
138 pub(super) fn parse_item_common(
139 &mut self,
140 attrs: AttrWrapper,
141 mac_allowed: bool,
142 attrs_allowed: bool,
143 fn_parse_mode: FnParseMode,
144 force_collect: ForceCollect,
145 ) -> PResult<'a, Option<Item>> {
146 if let Some(item) =
147 self.eat_metavar_seq(MetaVarKind::Item, |this| this.parse_item(ForceCollect::Yes))
148 {
149 let mut item = item.expect("an actual item");
150 attrs.prepend_to_nt_inner(&mut item.attrs);
151 return Ok(Some(*item));
152 }
153
154 self.collect_tokens(None, attrs, force_collect, |this, mut attrs| {
155 let lo = this.token.span;
156 let vis = this.parse_visibility(FollowedByType::No)?;
157 let mut def = this.parse_defaultness();
158 let kind = this.parse_item_kind(
159 &mut attrs,
160 mac_allowed,
161 lo,
162 &vis,
163 &mut def,
164 fn_parse_mode,
165 Case::Sensitive,
166 )?;
167 if let Some(kind) = kind {
168 this.error_on_unconsumed_default(def, &kind);
169 let span = lo.to(this.prev_token.span);
170 let id = DUMMY_NODE_ID;
171 let item = Item { attrs, id, kind, vis, span, tokens: None };
172 return Ok((Some(item), Trailing::No, UsePreAttrPos::No));
173 }
174
175 if !matches!(vis.kind, VisibilityKind::Inherited) {
177 this.dcx().emit_err(errors::VisibilityNotFollowedByItem { span: vis.span, vis });
178 }
179
180 if let Defaultness::Default(span) = def {
181 this.dcx().emit_err(errors::DefaultNotFollowedByItem { span });
182 }
183
184 if !attrs_allowed {
185 this.recover_attrs_no_item(&attrs)?;
186 }
187 Ok((None, Trailing::No, UsePreAttrPos::No))
188 })
189 }
190
191 fn error_on_unconsumed_default(&self, def: Defaultness, kind: &ItemKind) {
193 if let Defaultness::Default(span) = def {
194 self.dcx().emit_err(errors::InappropriateDefault {
195 span,
196 article: kind.article(),
197 descr: kind.descr(),
198 });
199 }
200 }
201
202 fn parse_item_kind(
204 &mut self,
205 attrs: &mut AttrVec,
206 macros_allowed: bool,
207 lo: Span,
208 vis: &Visibility,
209 def: &mut Defaultness,
210 fn_parse_mode: FnParseMode,
211 case: Case,
212 ) -> PResult<'a, Option<ItemKind>> {
213 let check_pub = def == &Defaultness::Final;
214 let mut def_ = || mem::replace(def, Defaultness::Final);
215
216 let info = if !self.is_use_closure() && self.eat_keyword_case(exp!(Use), case) {
217 self.parse_use_item()?
218 } else if self.check_fn_front_matter(check_pub, case) {
219 let (ident, sig, generics, contract, body) =
221 self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
222 ItemKind::Fn(Box::new(Fn {
223 defaultness: def_(),
224 ident,
225 sig,
226 generics,
227 contract,
228 body,
229 define_opaque: None,
230 eii_impls: ThinVec::new(),
231 }))
232 } else if self.eat_keyword_case(exp!(Extern), case) {
233 if self.eat_keyword_case(exp!(Crate), case) {
234 self.parse_item_extern_crate()?
236 } else {
237 self.parse_item_foreign_mod(attrs, Safety::Default)?
239 }
240 } else if self.is_unsafe_foreign_mod() {
241 let safety = self.parse_safety(Case::Sensitive);
243 self.expect_keyword(exp!(Extern))?;
244 self.parse_item_foreign_mod(attrs, safety)?
245 } else if let Some(safety) = self.parse_global_static_front_matter(case) {
246 let mutability = self.parse_mutability();
248 self.parse_static_item(safety, mutability)?
249 } else if self.check_keyword_case(exp!(Trait), case) || self.check_trait_front_matter() {
250 self.parse_item_trait(attrs, lo)?
252 } else if self.check_impl_frontmatter() {
253 self.parse_item_impl(attrs, def_())?
255 } else if let Const::Yes(const_span) = self.parse_constness(case) {
256 self.recover_const_mut(const_span);
258 self.recover_missing_kw_before_item()?;
259 let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?;
260 ItemKind::Const(Box::new(ConstItem {
261 defaultness: def_(),
262 ident,
263 generics,
264 ty,
265 rhs,
266 define_opaque: None,
267 }))
268 } else if self.is_reuse_path_item() {
269 self.parse_item_delegation()?
270 } else if self.check_keyword_case(exp!(Mod), case)
271 || self.check_keyword_case(exp!(Unsafe), case) && self.is_keyword_ahead(1, &[kw::Mod])
272 {
273 self.parse_item_mod(attrs)?
275 } else if self.eat_keyword_case(exp!(Type), case) {
276 self.parse_type_alias(def_())?
278 } else if self.eat_keyword_case(exp!(Enum), case) {
279 self.parse_item_enum()?
281 } else if self.eat_keyword_case(exp!(Struct), case) {
282 self.parse_item_struct()?
284 } else if self.is_kw_followed_by_ident(kw::Union) {
285 self.bump(); self.parse_item_union()?
288 } else if self.is_builtin() {
289 return self.parse_item_builtin();
291 } else if self.eat_keyword_case(exp!(Macro), case) {
292 self.parse_item_decl_macro(lo)?
294 } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() {
295 self.parse_item_macro_rules(vis, has_bang)?
297 } else if self.isnt_macro_invocation()
298 && (self.token.is_ident_named(sym::import)
299 || self.token.is_ident_named(sym::using)
300 || self.token.is_ident_named(sym::include)
301 || self.token.is_ident_named(sym::require))
302 {
303 return self.recover_import_as_use();
304 } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
305 self.recover_missing_kw_before_item()?;
306 return Ok(None);
307 } else if self.isnt_macro_invocation() && case == Case::Sensitive {
308 _ = def_;
309
310 return self.parse_item_kind(
312 attrs,
313 macros_allowed,
314 lo,
315 vis,
316 def,
317 fn_parse_mode,
318 Case::Insensitive,
319 );
320 } else if macros_allowed && self.check_path() {
321 if self.isnt_macro_invocation() {
322 self.recover_missing_kw_before_item()?;
323 }
324 ItemKind::MacCall(Box::new(self.parse_item_macro(vis)?))
326 } else {
327 return Ok(None);
328 };
329 Ok(Some(info))
330 }
331
332 fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
333 let span = self.token.span;
334 let token_name = super::token_descr(&self.token);
335 let snapshot = self.create_snapshot_for_diagnostic();
336 self.bump();
337 match self.parse_use_item() {
338 Ok(u) => {
339 self.dcx().emit_err(errors::RecoverImportAsUse { span, token_name });
340 Ok(Some(u))
341 }
342 Err(e) => {
343 e.cancel();
344 self.restore_snapshot(snapshot);
345 Ok(None)
346 }
347 }
348 }
349
350 fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
351 let tree = self.parse_use_tree()?;
352 if let Err(mut e) = self.expect_semi() {
353 match tree.kind {
354 UseTreeKind::Glob => {
355 e.note("the wildcard token must be last on the path");
356 }
357 UseTreeKind::Nested { .. } => {
358 e.note("glob-like brace syntax must be last on the path");
359 }
360 _ => (),
361 }
362 return Err(e);
363 }
364 Ok(ItemKind::Use(tree))
365 }
366
367 pub(super) fn is_path_start_item(&mut self) -> bool {
369 self.is_kw_followed_by_ident(kw::Union) || self.is_reuse_path_item()
371 || self.check_trait_front_matter() || self.is_async_fn() || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) }
375
376 fn is_reuse_path_item(&mut self) -> bool {
377 self.token.is_keyword(kw::Reuse)
379 && self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep)
380 }
381
382 fn isnt_macro_invocation(&mut self) -> bool {
384 self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep)
385 }
386
387 fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
390 let is_pub = self.prev_token.is_keyword(kw::Pub);
391 let is_const = self.prev_token.is_keyword(kw::Const);
392 let ident_span = self.token.span;
393 let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span };
394 let insert_span = ident_span.shrink_to_lo();
395
396 let ident = if self.token.is_ident()
397 && (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
398 && self.look_ahead(1, |t| {
399 matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen)
400 }) {
401 self.parse_ident().unwrap()
402 } else {
403 return Ok(());
404 };
405
406 let mut found_generics = false;
407 if self.check(exp!(Lt)) {
408 found_generics = true;
409 self.eat_to_tokens(&[exp!(Gt)]);
410 self.bump(); }
412
413 let err = if self.check(exp!(OpenBrace)) {
414 if self.look_ahead(1, |t| *t == token::CloseBrace) {
416 Some(errors::MissingKeywordForItemDefinition::EnumOrStruct { span })
418 } else if self.look_ahead(2, |t| *t == token::Colon)
419 || self.look_ahead(3, |t| *t == token::Colon)
420 {
421 Some(errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident })
423 } else {
424 Some(errors::MissingKeywordForItemDefinition::Enum { span, insert_span, ident })
425 }
426 } else if self.check(exp!(OpenParen)) {
427 self.bump(); let is_method = self.recover_self_param();
430
431 self.consume_block(exp!(OpenParen), exp!(CloseParen), ConsumeClosingDelim::Yes);
432
433 let err = if self.check(exp!(RArrow)) || self.check(exp!(OpenBrace)) {
434 self.eat_to_tokens(&[exp!(OpenBrace)]);
435 self.bump(); self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
437 if is_method {
438 errors::MissingKeywordForItemDefinition::Method { span, insert_span, ident }
439 } else {
440 errors::MissingKeywordForItemDefinition::Function { span, insert_span, ident }
441 }
442 } else if is_pub && self.check(exp!(Semi)) {
443 errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident }
444 } else {
445 errors::MissingKeywordForItemDefinition::Ambiguous {
446 span,
447 subdiag: if found_generics {
448 None
449 } else if let Ok(snippet) = self.span_to_snippet(ident_span) {
450 Some(errors::AmbiguousMissingKwForItemSub::SuggestMacro {
451 span: ident_span,
452 snippet,
453 })
454 } else {
455 Some(errors::AmbiguousMissingKwForItemSub::HelpMacro)
456 },
457 }
458 };
459 Some(err)
460 } else if found_generics {
461 Some(errors::MissingKeywordForItemDefinition::Ambiguous { span, subdiag: None })
462 } else {
463 None
464 };
465
466 if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
467 }
468
469 fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemKind>> {
470 Ok(None)
472 }
473
474 fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
476 let path = self.parse_path(PathStyle::Mod)?; self.expect(exp!(Bang))?; match self.parse_delim_args() {
479 Ok(args) => {
481 self.eat_semi_for_macro_if_needed(&args);
482 self.complain_if_pub_macro(vis, false);
483 Ok(MacCall { path, args })
484 }
485
486 Err(mut err) => {
487 if self.token.is_ident()
489 && let [segment] = path.segments.as_slice()
490 && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some()
491 {
492 err.span_suggestion(
493 path.span,
494 "perhaps you meant to define a macro",
495 "macro_rules",
496 Applicability::MachineApplicable,
497 );
498 }
499 Err(err)
500 }
501 }
502 }
503
504 fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
506 let ([start @ end] | [start, .., end]) = attrs else {
507 return Ok(());
508 };
509 let msg = if end.is_doc_comment() {
510 "expected item after doc comment"
511 } else {
512 "expected item after attributes"
513 };
514 let mut err = self.dcx().struct_span_err(end.span, msg);
515 if end.is_doc_comment() {
516 err.span_label(end.span, "this doc comment doesn't document anything");
517 } else if self.token == TokenKind::Semi {
518 err.span_suggestion_verbose(
519 self.token.span,
520 "consider removing this semicolon",
521 "",
522 Applicability::MaybeIncorrect,
523 );
524 }
525 if let [.., penultimate, _] = attrs {
526 err.span_label(start.span.to(penultimate.span), "other attributes here");
527 }
528 Err(err)
529 }
530
531 fn is_async_fn(&self) -> bool {
532 self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
533 }
534
535 fn parse_polarity(&mut self) -> ast::ImplPolarity {
536 if self.check(exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) {
538 self.bump(); ast::ImplPolarity::Negative(self.prev_token.span)
540 } else {
541 ast::ImplPolarity::Positive
542 }
543 }
544
545 fn parse_item_impl(
560 &mut self,
561 attrs: &mut AttrVec,
562 defaultness: Defaultness,
563 ) -> PResult<'a, ItemKind> {
564 let mut constness = self.parse_constness(Case::Sensitive);
565 let safety = self.parse_safety(Case::Sensitive);
566 self.expect_keyword(exp!(Impl))?;
567
568 let mut generics = if self.choose_generics_over_qpath(0) {
570 self.parse_generics()?
571 } else {
572 let mut generics = Generics::default();
573 generics.span = self.prev_token.span.shrink_to_hi();
576 generics
577 };
578
579 if let Const::No = constness {
580 constness = self.parse_constness(Case::Sensitive);
582 }
583
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 let of_trait =
668 Some(Box::new(TraitImplHeader { defaultness, safety, polarity, trait_ref }));
669 (of_trait, ty_second)
670 }
671 None => {
672 let self_ty = ty_first;
673 let error = |modifier, modifier_name, modifier_span| {
674 self.dcx().create_err(errors::TraitImplModifierInInherentImpl {
675 span: self_ty.span,
676 modifier,
677 modifier_name,
678 modifier_span,
679 self_ty: self_ty.span,
680 })
681 };
682
683 if let Safety::Unsafe(span) = safety {
684 error("unsafe", "unsafe", span).with_code(E0197).emit();
685 }
686 if let ImplPolarity::Negative(span) = polarity {
687 error("!", "negative", span).emit();
688 }
689 if let Defaultness::Default(def_span) = defaultness {
690 error("default", "default", def_span).emit();
691 }
692 if let Const::Yes(span) = constness {
693 self.psess.gated_spans.gate(sym::const_trait_impl, span);
694 }
695 (None, self_ty)
696 }
697 };
698
699 Ok(ItemKind::Impl(Impl { generics, of_trait, self_ty, items: impl_items, constness }))
700 }
701
702 fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> {
703 let span = self.token.span;
704 self.expect_keyword(exp!(Reuse))?;
705
706 let (qself, path) = if self.eat_lt() {
707 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
708 (Some(qself), path)
709 } else {
710 (None, self.parse_path(PathStyle::Expr)?)
711 };
712
713 let rename = |this: &mut Self| {
714 Ok(if this.eat_keyword(exp!(As)) { Some(this.parse_ident()?) } else { None })
715 };
716 let body = |this: &mut Self| {
717 Ok(if this.check(exp!(OpenBrace)) {
718 Some(this.parse_block()?)
719 } else {
720 this.expect(exp!(Semi))?;
721 None
722 })
723 };
724
725 let item_kind = if self.eat_path_sep() {
726 let suffixes = if self.eat(exp!(Star)) {
727 None
728 } else {
729 let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?));
730 Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0)
731 };
732 let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? };
733 ItemKind::DelegationMac(Box::new(deleg))
734 } else {
735 let rename = rename(self)?;
736 let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
737 let deleg = Delegation {
738 id: DUMMY_NODE_ID,
739 qself,
740 path,
741 ident,
742 rename,
743 body: body(self)?,
744 from_glob: false,
745 };
746 ItemKind::Delegation(Box::new(deleg))
747 };
748
749 let span = span.to(self.prev_token.span);
750 self.psess.gated_spans.gate(sym::fn_delegation, span);
751
752 Ok(item_kind)
753 }
754
755 fn parse_item_list<T>(
756 &mut self,
757 attrs: &mut AttrVec,
758 mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
759 ) -> PResult<'a, ThinVec<T>> {
760 let open_brace_span = self.token.span;
761
762 if self.token == TokenKind::Semi {
764 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
765 self.bump();
766 return Ok(ThinVec::new());
767 }
768
769 self.expect(exp!(OpenBrace))?;
770 attrs.extend(self.parse_inner_attributes()?);
771
772 let mut items = ThinVec::new();
773 while !self.eat(exp!(CloseBrace)) {
774 if self.recover_doc_comment_before_brace() {
775 continue;
776 }
777 self.recover_vcs_conflict_marker();
778 match parse_item(self) {
779 Ok(None) => {
780 let mut is_unnecessary_semicolon = !items.is_empty()
781 && self
799 .span_to_snippet(self.prev_token.span)
800 .is_ok_and(|snippet| snippet == "}")
801 && self.token == token::Semi;
802 let mut semicolon_span = self.token.span;
803 if !is_unnecessary_semicolon {
804 is_unnecessary_semicolon =
806 self.token == token::OpenBrace && self.prev_token == token::Semi;
807 semicolon_span = self.prev_token.span;
808 }
809 let non_item_span = self.token.span;
811 let is_let = self.token.is_keyword(kw::Let);
812
813 let mut err =
814 self.dcx().struct_span_err(non_item_span, "non-item in item list");
815 self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
816 if is_let {
817 err.span_suggestion_verbose(
818 non_item_span,
819 "consider using `const` instead of `let` for associated const",
820 "const",
821 Applicability::MachineApplicable,
822 );
823 } else {
824 err.span_label(open_brace_span, "item list starts here")
825 .span_label(non_item_span, "non-item starts here")
826 .span_label(self.prev_token.span, "item list ends here");
827 }
828 if is_unnecessary_semicolon {
829 err.span_suggestion(
830 semicolon_span,
831 "consider removing this semicolon",
832 "",
833 Applicability::MaybeIncorrect,
834 );
835 }
836 err.emit();
837 break;
838 }
839 Ok(Some(item)) => items.extend(item),
840 Err(err) => {
841 self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
842 err.with_span_label(
843 open_brace_span,
844 "while parsing this item list starting here",
845 )
846 .with_span_label(self.prev_token.span, "the item list ends here")
847 .emit();
848 break;
849 }
850 }
851 }
852 Ok(items)
853 }
854
855 fn recover_doc_comment_before_brace(&mut self) -> bool {
857 if let token::DocComment(..) = self.token.kind {
858 if self.look_ahead(1, |tok| tok == &token::CloseBrace) {
859 struct_span_code_err!(
861 self.dcx(),
862 self.token.span,
863 E0584,
864 "found a documentation comment that doesn't document anything",
865 )
866 .with_span_label(self.token.span, "this doc comment doesn't document anything")
867 .with_help(
868 "doc comments must come before what they document, if a comment was \
869 intended use `//`",
870 )
871 .emit();
872 self.bump();
873 return true;
874 }
875 }
876 false
877 }
878
879 fn parse_defaultness(&mut self) -> Defaultness {
881 if self.check_keyword(exp!(Default))
885 && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
886 {
887 self.bump(); Defaultness::Default(self.prev_token_uninterpolated_span())
889 } else {
890 Defaultness::Final
891 }
892 }
893
894 fn check_trait_front_matter(&mut self) -> bool {
896 self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait])
898 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
900 || 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]))
901 || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Trait, kw::Auto]))
902 }
903
904 fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
906 let constness = self.parse_constness(Case::Sensitive);
907 if let Const::Yes(span) = constness {
908 self.psess.gated_spans.gate(sym::const_trait_impl, span);
909 }
910 let safety = self.parse_safety(Case::Sensitive);
911 let is_auto = if self.eat_keyword(exp!(Auto)) {
913 self.psess.gated_spans.gate(sym::auto_traits, self.prev_token.span);
914 IsAuto::Yes
915 } else {
916 IsAuto::No
917 };
918
919 self.expect_keyword(exp!(Trait))?;
920 let ident = self.parse_ident()?;
921 let mut generics = self.parse_generics()?;
922
923 let had_colon = self.eat(exp!(Colon));
925 let span_at_colon = self.prev_token.span;
926 let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
927
928 let span_before_eq = self.prev_token.span;
929 if self.eat(exp!(Eq)) {
930 if had_colon {
932 let span = span_at_colon.to(span_before_eq);
933 self.dcx().emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
934 }
935
936 let bounds = self.parse_generic_bounds()?;
937 generics.where_clause = self.parse_where_clause()?;
938 self.expect_semi()?;
939
940 let whole_span = lo.to(self.prev_token.span);
941 if is_auto == IsAuto::Yes {
942 self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
943 }
944 if let Safety::Unsafe(_) = safety {
945 self.dcx().emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span });
946 }
947
948 self.psess.gated_spans.gate(sym::trait_alias, whole_span);
949
950 Ok(ItemKind::TraitAlias(Box::new(TraitAlias { constness, ident, generics, bounds })))
951 } else {
952 generics.where_clause = self.parse_where_clause()?;
954 let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
955 Ok(ItemKind::Trait(Box::new(Trait {
956 constness,
957 is_auto,
958 safety,
959 ident,
960 generics,
961 bounds,
962 items,
963 })))
964 }
965 }
966
967 pub fn parse_impl_item(
968 &mut self,
969 force_collect: ForceCollect,
970 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
971 let fn_parse_mode =
972 FnParseMode { req_name: |_, _| true, context: FnContext::Impl, req_body: true };
973 self.parse_assoc_item(fn_parse_mode, force_collect)
974 }
975
976 pub fn parse_trait_item(
977 &mut self,
978 force_collect: ForceCollect,
979 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
980 let fn_parse_mode = FnParseMode {
981 req_name: |edition, _| edition >= Edition::Edition2018,
982 context: FnContext::Trait,
983 req_body: false,
984 };
985 self.parse_assoc_item(fn_parse_mode, force_collect)
986 }
987
988 fn parse_assoc_item(
990 &mut self,
991 fn_parse_mode: FnParseMode,
992 force_collect: ForceCollect,
993 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
994 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
995 |Item { attrs, id, span, vis, kind, tokens }| {
996 let kind = match AssocItemKind::try_from(kind) {
997 Ok(kind) => kind,
998 Err(kind) => match kind {
999 ItemKind::Static(box StaticItem {
1000 ident,
1001 ty,
1002 safety: _,
1003 mutability: _,
1004 expr,
1005 define_opaque,
1006 }) => {
1007 self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
1008 let rhs = expr.map(ConstItemRhs::Body);
1009 AssocItemKind::Const(Box::new(ConstItem {
1010 defaultness: Defaultness::Final,
1011 ident,
1012 generics: Generics::default(),
1013 ty,
1014 rhs,
1015 define_opaque,
1016 }))
1017 }
1018 _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
1019 },
1020 };
1021 Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1022 },
1023 ))
1024 }
1025
1026 fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
1032 let ident = self.parse_ident()?;
1033 let mut generics = self.parse_generics()?;
1034
1035 let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() };
1037 generics.where_clause = self.parse_where_clause()?;
1038
1039 let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None };
1040
1041 let after_where_clause = self.parse_where_clause()?;
1042
1043 self.expect_semi()?;
1044
1045 Ok(ItemKind::TyAlias(Box::new(TyAlias {
1046 defaultness,
1047 ident,
1048 generics,
1049 after_where_clause,
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<Box<ForeignItem>>>> {
1241 let fn_parse_mode = FnParseMode {
1242 req_name: |_, is_dot_dot_dot| is_dot_dot_dot == IsDotDotDot::No,
1243 context: FnContext::Free,
1244 req_body: false,
1245 };
1246 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
1247 |Item { attrs, id, span, vis, kind, tokens }| {
1248 let kind = match ForeignItemKind::try_from(kind) {
1249 Ok(kind) => kind,
1250 Err(kind) => match kind {
1251 ItemKind::Const(box ConstItem { ident, ty, rhs, .. }) => {
1252 let const_span = Some(span.with_hi(ident.span.lo()))
1253 .filter(|span| span.can_be_used_for_suggestions());
1254 self.dcx().emit_err(errors::ExternItemCannotBeConst {
1255 ident_span: ident.span,
1256 const_span,
1257 });
1258 ForeignItemKind::Static(Box::new(StaticItem {
1259 ident,
1260 ty,
1261 mutability: Mutability::Not,
1262 expr: rhs.map(|b| match b {
1263 ConstItemRhs::TypeConst(anon_const) => anon_const.value,
1264 ConstItemRhs::Body(expr) => expr,
1265 }),
1266 safety: Safety::Default,
1267 define_opaque: None,
1268 }))
1269 }
1270 _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
1271 },
1272 };
1273 Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1274 },
1275 ))
1276 }
1277
1278 fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
1279 let span = self.psess.source_map().guess_head_span(span);
1281 let descr = kind.descr();
1282 let help = match kind {
1283 ItemKind::DelegationMac(deleg) if deleg.suffixes.is_none() => false,
1284 _ => true,
1285 };
1286 self.dcx().emit_err(errors::BadItemKind { span, descr, ctx, help });
1287 None
1288 }
1289
1290 fn is_use_closure(&self) -> bool {
1291 if self.token.is_keyword(kw::Use) {
1292 self.look_ahead(1, |token| {
1294 let dist =
1296 if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 };
1297
1298 self.look_ahead(dist, |token| matches!(token.kind, token::Or | token::OrOr))
1299 })
1300 } else {
1301 false
1302 }
1303 }
1304
1305 fn is_unsafe_foreign_mod(&self) -> bool {
1306 if !self.token.is_keyword(kw::Unsafe) {
1308 return false;
1309 }
1310 if !self.is_keyword_ahead(1, &[kw::Extern]) {
1312 return false;
1313 }
1314
1315 let n = if self.look_ahead(2, |t| t.can_begin_string_literal()) { 3 } else { 2 };
1317
1318 self.tree_look_ahead(n, |t| matches!(t, TokenTree::Delimited(_, _, Delimiter::Brace, _)))
1323 == Some(true)
1324 }
1325
1326 fn parse_global_static_front_matter(&mut self, case: Case) -> Option<Safety> {
1327 let is_global_static = if self.check_keyword_case(exp!(Static), case) {
1328 !self.look_ahead(1, |token| {
1330 if token.is_keyword_case(kw::Move, case) || token.is_keyword_case(kw::Use, case) {
1331 return true;
1332 }
1333 matches!(token.kind, token::Or | token::OrOr)
1334 })
1335 } else {
1336 (self.check_keyword_case(exp!(Unsafe), case)
1338 || self.check_keyword_case(exp!(Safe), case))
1339 && self.look_ahead(1, |t| t.is_keyword_case(kw::Static, case))
1340 };
1341
1342 if is_global_static {
1343 let safety = self.parse_safety(case);
1344 let _ = self.eat_keyword_case(exp!(Static), case);
1345 Some(safety)
1346 } else {
1347 None
1348 }
1349 }
1350
1351 fn recover_const_mut(&mut self, const_span: Span) {
1353 if self.eat_keyword(exp!(Mut)) {
1354 let span = self.prev_token.span;
1355 self.dcx()
1356 .emit_err(errors::ConstGlobalCannotBeMutable { ident_span: span, const_span });
1357 } else if self.eat_keyword(exp!(Let)) {
1358 let span = self.prev_token.span;
1359 self.dcx().emit_err(errors::ConstLetMutuallyExclusive { span: const_span.to(span) });
1360 }
1361 }
1362
1363 fn parse_static_item(
1370 &mut self,
1371 safety: Safety,
1372 mutability: Mutability,
1373 ) -> PResult<'a, ItemKind> {
1374 let ident = self.parse_ident()?;
1375
1376 if self.token == TokenKind::Lt && self.may_recover() {
1377 let generics = self.parse_generics()?;
1378 self.dcx().emit_err(errors::StaticWithGenerics { span: generics.span });
1379 }
1380
1381 let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
1384 (true, false) => self.parse_ty()?,
1385 (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
1388 };
1389
1390 let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1391
1392 self.expect_semi()?;
1393
1394 let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
1395 Ok(ItemKind::Static(Box::new(item)))
1396 }
1397
1398 fn parse_const_item(
1404 &mut self,
1405 attrs: &[Attribute],
1406 ) -> PResult<'a, (Ident, Generics, Box<Ty>, Option<ast::ConstItemRhs>)> {
1407 let ident = self.parse_ident_or_underscore()?;
1408
1409 let mut generics = self.parse_generics()?;
1410
1411 if !generics.span.is_empty() {
1414 self.psess.gated_spans.gate(sym::generic_const_items, generics.span);
1415 }
1416
1417 let ty = match (
1420 self.eat(exp!(Colon)),
1421 self.check(exp!(Eq)) | self.check(exp!(Semi)) | self.check_keyword(exp!(Where)),
1422 ) {
1423 (true, false) => self.parse_ty()?,
1424 (colon, _) => self.recover_missing_global_item_type(colon, None),
1426 };
1427
1428 let before_where_clause =
1431 if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() };
1432
1433 let rhs = if self.eat(exp!(Eq)) {
1434 if attr::contains_name(attrs, sym::type_const) {
1435 Some(ConstItemRhs::TypeConst(self.parse_const_arg()?))
1436 } else {
1437 Some(ConstItemRhs::Body(self.parse_expr()?))
1438 }
1439 } else {
1440 None
1441 };
1442
1443 let after_where_clause = self.parse_where_clause()?;
1444
1445 if before_where_clause.has_where_token
1449 && let Some(rhs) = &rhs
1450 {
1451 self.dcx().emit_err(errors::WhereClauseBeforeConstBody {
1452 span: before_where_clause.span,
1453 name: ident.span,
1454 body: rhs.span(),
1455 sugg: if !after_where_clause.has_where_token {
1456 self.psess.source_map().span_to_snippet(rhs.span()).ok().map(|body_s| {
1457 errors::WhereClauseBeforeConstBodySugg {
1458 left: before_where_clause.span.shrink_to_lo(),
1459 snippet: body_s,
1460 right: before_where_clause.span.shrink_to_hi().to(rhs.span()),
1461 }
1462 })
1463 } else {
1464 None
1467 },
1468 });
1469 }
1470
1471 let mut predicates = before_where_clause.predicates;
1478 predicates.extend(after_where_clause.predicates);
1479 let where_clause = WhereClause {
1480 has_where_token: before_where_clause.has_where_token
1481 || after_where_clause.has_where_token,
1482 predicates,
1483 span: if after_where_clause.has_where_token {
1484 after_where_clause.span
1485 } else {
1486 before_where_clause.span
1487 },
1488 };
1489
1490 if where_clause.has_where_token {
1491 self.psess.gated_spans.gate(sym::generic_const_items, where_clause.span);
1492 }
1493
1494 generics.where_clause = where_clause;
1495
1496 self.expect_semi()?;
1497
1498 Ok((ident, generics, ty, rhs))
1499 }
1500
1501 fn recover_missing_global_item_type(
1504 &mut self,
1505 colon_present: bool,
1506 m: Option<Mutability>,
1507 ) -> Box<Ty> {
1508 let kind = match m {
1511 Some(Mutability::Mut) => "static mut",
1512 Some(Mutability::Not) => "static",
1513 None => "const",
1514 };
1515
1516 let colon = match colon_present {
1517 true => "",
1518 false => ":",
1519 };
1520
1521 let span = self.prev_token.span.shrink_to_hi();
1522 let err = self.dcx().create_err(errors::MissingConstType { span, colon, kind });
1523 err.stash(span, StashKey::ItemNoType);
1524
1525 Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
1528 }
1529
1530 fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
1532 if self.token.is_keyword(kw::Struct) {
1533 let span = self.prev_token.span.to(self.token.span);
1534 let err = errors::EnumStructMutuallyExclusive { span };
1535 if self.look_ahead(1, |t| t.is_ident()) {
1536 self.bump();
1537 self.dcx().emit_err(err);
1538 } else {
1539 return Err(self.dcx().create_err(err));
1540 }
1541 }
1542
1543 let prev_span = self.prev_token.span;
1544 let ident = self.parse_ident()?;
1545 let mut generics = self.parse_generics()?;
1546 generics.where_clause = self.parse_where_clause()?;
1547
1548 let (variants, _) = if self.token == TokenKind::Semi {
1550 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
1551 self.bump();
1552 (thin_vec![], Trailing::No)
1553 } else {
1554 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1555 p.parse_enum_variant(ident.span)
1556 })
1557 .map_err(|mut err| {
1558 err.span_label(ident.span, "while parsing this enum");
1559 if self.prev_token.is_non_reserved_ident() && self.token == token::Colon {
1561 let snapshot = self.create_snapshot_for_diagnostic();
1562 self.bump();
1563 match self.parse_ty() {
1564 Ok(_) => {
1565 err.span_suggestion_verbose(
1566 prev_span,
1567 "perhaps you meant to use `struct` here",
1568 "struct",
1569 Applicability::MaybeIncorrect,
1570 );
1571 }
1572 Err(e) => {
1573 e.cancel();
1574 }
1575 }
1576 self.restore_snapshot(snapshot);
1577 }
1578 self.eat_to_tokens(&[exp!(CloseBrace)]);
1579 self.bump(); err
1581 })?
1582 };
1583
1584 let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
1585 Ok(ItemKind::Enum(ident, generics, enum_definition))
1586 }
1587
1588 fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
1589 self.recover_vcs_conflict_marker();
1590 let variant_attrs = self.parse_outer_attributes()?;
1591 self.recover_vcs_conflict_marker();
1592 let help = "enum variants can be `Variant`, `Variant = <integer>`, \
1593 `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`";
1594 self.collect_tokens(None, variant_attrs, ForceCollect::No, |this, variant_attrs| {
1595 let vlo = this.token.span;
1596
1597 let vis = this.parse_visibility(FollowedByType::No)?;
1598 if !this.recover_nested_adt_item(kw::Enum)? {
1599 return Ok((None, Trailing::No, UsePreAttrPos::No));
1600 }
1601 let ident = this.parse_field_ident("enum", vlo)?;
1602
1603 if this.token == token::Bang {
1604 if let Err(err) = this.unexpected() {
1605 err.with_note(fluent::parse_macro_expands_to_enum_variant).emit();
1606 }
1607
1608 this.bump();
1609 this.parse_delim_args()?;
1610
1611 return Ok((None, Trailing::from(this.token == token::Comma), UsePreAttrPos::No));
1612 }
1613
1614 let struct_def = if this.check(exp!(OpenBrace)) {
1615 let (fields, recovered) =
1617 match this.parse_record_struct_body("struct", ident.span, false) {
1618 Ok((fields, recovered)) => (fields, recovered),
1619 Err(mut err) => {
1620 if this.token == token::Colon {
1621 return Err(err);
1623 }
1624 this.eat_to_tokens(&[exp!(CloseBrace)]);
1625 this.bump(); err.span_label(span, "while parsing this enum");
1627 err.help(help);
1628 let guar = err.emit();
1629 (thin_vec![], Recovered::Yes(guar))
1630 }
1631 };
1632 VariantData::Struct { fields, recovered }
1633 } else if this.check(exp!(OpenParen)) {
1634 let body = match this.parse_tuple_struct_body() {
1635 Ok(body) => body,
1636 Err(mut err) => {
1637 if this.token == token::Colon {
1638 return Err(err);
1640 }
1641 this.eat_to_tokens(&[exp!(CloseParen)]);
1642 this.bump(); err.span_label(span, "while parsing this enum");
1644 err.help(help);
1645 err.emit();
1646 thin_vec![]
1647 }
1648 };
1649 VariantData::Tuple(body, DUMMY_NODE_ID)
1650 } else {
1651 VariantData::Unit(DUMMY_NODE_ID)
1652 };
1653
1654 let disr_expr = if this.eat(exp!(Eq)) {
1655 Some(this.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?)
1656 } else {
1657 None
1658 };
1659
1660 let vr = ast::Variant {
1661 ident,
1662 vis,
1663 id: DUMMY_NODE_ID,
1664 attrs: variant_attrs,
1665 data: struct_def,
1666 disr_expr,
1667 span: vlo.to(this.prev_token.span),
1668 is_placeholder: false,
1669 };
1670
1671 Ok((Some(vr), Trailing::from(this.token == token::Comma), UsePreAttrPos::No))
1672 })
1673 .map_err(|mut err| {
1674 err.help(help);
1675 err
1676 })
1677 }
1678
1679 fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
1681 let ident = self.parse_ident()?;
1682
1683 let mut generics = self.parse_generics()?;
1684
1685 let vdata = if self.token.is_keyword(kw::Where) {
1700 let tuple_struct_body;
1701 (generics.where_clause, tuple_struct_body) =
1702 self.parse_struct_where_clause(ident, generics.span)?;
1703
1704 if let Some(body) = tuple_struct_body {
1705 let body = VariantData::Tuple(body, DUMMY_NODE_ID);
1707 self.expect_semi()?;
1708 body
1709 } else if self.eat(exp!(Semi)) {
1710 VariantData::Unit(DUMMY_NODE_ID)
1712 } else {
1713 let (fields, recovered) = self.parse_record_struct_body(
1715 "struct",
1716 ident.span,
1717 generics.where_clause.has_where_token,
1718 )?;
1719 VariantData::Struct { fields, recovered }
1720 }
1721 } else if self.eat(exp!(Semi)) {
1723 VariantData::Unit(DUMMY_NODE_ID)
1724 } else if self.token == token::OpenBrace {
1726 let (fields, recovered) = self.parse_record_struct_body(
1727 "struct",
1728 ident.span,
1729 generics.where_clause.has_where_token,
1730 )?;
1731 VariantData::Struct { fields, recovered }
1732 } else if self.token == token::OpenParen {
1734 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1735 generics.where_clause = self.parse_where_clause()?;
1736 self.expect_semi()?;
1737 body
1738 } else {
1739 let err = errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token);
1740 return Err(self.dcx().create_err(err));
1741 };
1742
1743 Ok(ItemKind::Struct(ident, generics, vdata))
1744 }
1745
1746 fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
1748 let ident = self.parse_ident()?;
1749
1750 let mut generics = self.parse_generics()?;
1751
1752 let vdata = if self.token.is_keyword(kw::Where) {
1753 generics.where_clause = self.parse_where_clause()?;
1754 let (fields, recovered) = self.parse_record_struct_body(
1755 "union",
1756 ident.span,
1757 generics.where_clause.has_where_token,
1758 )?;
1759 VariantData::Struct { fields, recovered }
1760 } else if self.token == token::OpenBrace {
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 {
1768 let token_str = super::token_descr(&self.token);
1769 let msg = format!("expected `where` or `{{` after union name, found {token_str}");
1770 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1771 err.span_label(self.token.span, "expected `where` or `{` after union name");
1772 return Err(err);
1773 };
1774
1775 Ok(ItemKind::Union(ident, generics, vdata))
1776 }
1777
1778 pub(crate) fn parse_record_struct_body(
1783 &mut self,
1784 adt_ty: &str,
1785 ident_span: Span,
1786 parsed_where: bool,
1787 ) -> PResult<'a, (ThinVec<FieldDef>, Recovered)> {
1788 let mut fields = ThinVec::new();
1789 let mut recovered = Recovered::No;
1790 if self.eat(exp!(OpenBrace)) {
1791 while self.token != token::CloseBrace {
1792 match self.parse_field_def(adt_ty, ident_span) {
1793 Ok(field) => {
1794 fields.push(field);
1795 }
1796 Err(mut err) => {
1797 self.consume_block(
1798 exp!(OpenBrace),
1799 exp!(CloseBrace),
1800 ConsumeClosingDelim::No,
1801 );
1802 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1803 let guar = err.emit();
1804 recovered = Recovered::Yes(guar);
1805 break;
1806 }
1807 }
1808 }
1809 self.expect(exp!(CloseBrace))?;
1810 } else {
1811 let token_str = super::token_descr(&self.token);
1812 let where_str = if parsed_where { "" } else { "`where`, or " };
1813 let msg = format!("expected {where_str}`{{` after struct name, found {token_str}");
1814 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1815 err.span_label(self.token.span, format!("expected {where_str}`{{` after struct name",));
1816 return Err(err);
1817 }
1818
1819 Ok((fields, recovered))
1820 }
1821
1822 fn parse_unsafe_field(&mut self) -> Safety {
1823 if self.eat_keyword(exp!(Unsafe)) {
1825 let span = self.prev_token.span;
1826 self.psess.gated_spans.gate(sym::unsafe_fields, span);
1827 Safety::Unsafe(span)
1828 } else {
1829 Safety::Default
1830 }
1831 }
1832
1833 pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
1834 self.parse_paren_comma_seq(|p| {
1837 let attrs = p.parse_outer_attributes()?;
1838 p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
1839 let mut snapshot = None;
1840 if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
1841 snapshot = Some(p.create_snapshot_for_diagnostic());
1845 }
1846 let lo = p.token.span;
1847 let vis = match p.parse_visibility(FollowedByType::Yes) {
1848 Ok(vis) => vis,
1849 Err(err) => {
1850 if let Some(ref mut snapshot) = snapshot {
1851 snapshot.recover_vcs_conflict_marker();
1852 }
1853 return Err(err);
1854 }
1855 };
1856 let ty = match p.parse_ty() {
1859 Ok(ty) => ty,
1860 Err(err) => {
1861 if let Some(ref mut snapshot) = snapshot {
1862 snapshot.recover_vcs_conflict_marker();
1863 }
1864 return Err(err);
1865 }
1866 };
1867 let mut default = None;
1868 if p.token == token::Eq {
1869 let mut snapshot = p.create_snapshot_for_diagnostic();
1870 snapshot.bump();
1871 match snapshot.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst) {
1872 Ok(const_expr) => {
1873 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
1874 p.psess.gated_spans.gate(sym::default_field_values, sp);
1875 p.restore_snapshot(snapshot);
1876 default = Some(const_expr);
1877 }
1878 Err(err) => {
1879 err.cancel();
1880 }
1881 }
1882 }
1883
1884 Ok((
1885 FieldDef {
1886 span: lo.to(ty.span),
1887 vis,
1888 safety: Safety::Default,
1889 ident: None,
1890 id: DUMMY_NODE_ID,
1891 ty,
1892 default,
1893 attrs,
1894 is_placeholder: false,
1895 },
1896 Trailing::from(p.token == token::Comma),
1897 UsePreAttrPos::No,
1898 ))
1899 })
1900 })
1901 .map(|(r, _)| r)
1902 }
1903
1904 fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
1906 self.recover_vcs_conflict_marker();
1907 let attrs = self.parse_outer_attributes()?;
1908 self.recover_vcs_conflict_marker();
1909 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
1910 let lo = this.token.span;
1911 let vis = this.parse_visibility(FollowedByType::No)?;
1912 let safety = this.parse_unsafe_field();
1913 this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
1914 .map(|field| (field, Trailing::No, UsePreAttrPos::No))
1915 })
1916 }
1917
1918 fn parse_single_struct_field(
1920 &mut self,
1921 adt_ty: &str,
1922 lo: Span,
1923 vis: Visibility,
1924 safety: Safety,
1925 attrs: AttrVec,
1926 ident_span: Span,
1927 ) -> PResult<'a, FieldDef> {
1928 let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
1929 match self.token.kind {
1930 token::Comma => {
1931 self.bump();
1932 }
1933 token::Semi => {
1934 self.bump();
1935 let sp = self.prev_token.span;
1936 let mut err =
1937 self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
1938 err.span_suggestion_short(
1939 sp,
1940 "replace `;` with `,`",
1941 ",",
1942 Applicability::MachineApplicable,
1943 );
1944 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1945 err.emit();
1946 }
1947 token::CloseBrace => {}
1948 token::DocComment(..) => {
1949 let previous_span = self.prev_token.span;
1950 let mut err = errors::DocCommentDoesNotDocumentAnything {
1951 span: self.token.span,
1952 missing_comma: None,
1953 };
1954 self.bump(); if self.eat(exp!(Comma)) || self.token == token::CloseBrace {
1956 self.dcx().emit_err(err);
1957 } else {
1958 let sp = previous_span.shrink_to_hi();
1959 err.missing_comma = Some(sp);
1960 return Err(self.dcx().create_err(err));
1961 }
1962 }
1963 _ => {
1964 let sp = self.prev_token.span.shrink_to_hi();
1965 let msg =
1966 format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
1967
1968 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
1970 && let Some(last_segment) = segments.last()
1971 {
1972 let guar = self.check_trailing_angle_brackets(
1973 last_segment,
1974 &[exp!(Comma), exp!(CloseBrace)],
1975 );
1976 if let Some(_guar) = guar {
1977 let _ = self.eat(exp!(Comma));
1980
1981 return Ok(a_var);
1984 }
1985 }
1986
1987 let mut err = self.dcx().struct_span_err(sp, msg);
1988
1989 if self.token.is_ident()
1990 || (self.token == TokenKind::Pound
1991 && (self.look_ahead(1, |t| t == &token::OpenBracket)))
1992 {
1993 err.span_suggestion(
1996 sp,
1997 "try adding a comma",
1998 ",",
1999 Applicability::MachineApplicable,
2000 );
2001 err.emit();
2002 } else {
2003 return Err(err);
2004 }
2005 }
2006 }
2007 Ok(a_var)
2008 }
2009
2010 fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2011 if let Err(err) = self.expect(exp!(Colon)) {
2012 let sm = self.psess.source_map();
2013 let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2014 let semi_typo = self.token == token::Semi
2015 && self.look_ahead(1, |t| {
2016 t.is_path_start()
2017 && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2020 (Ok(l), Ok(r)) => l.line == r.line,
2021 _ => true,
2022 }
2023 });
2024 if eq_typo || semi_typo {
2025 self.bump();
2026 err.with_span_suggestion_short(
2028 self.prev_token.span,
2029 "field names and their types are separated with `:`",
2030 ":",
2031 Applicability::MachineApplicable,
2032 )
2033 .emit();
2034 } else {
2035 return Err(err);
2036 }
2037 }
2038 Ok(())
2039 }
2040
2041 fn parse_name_and_ty(
2043 &mut self,
2044 adt_ty: &str,
2045 lo: Span,
2046 vis: Visibility,
2047 safety: Safety,
2048 attrs: AttrVec,
2049 ) -> PResult<'a, FieldDef> {
2050 let name = self.parse_field_ident(adt_ty, lo)?;
2051 if self.token == token::Bang {
2052 if let Err(mut err) = self.unexpected() {
2053 err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2055 return Err(err);
2056 }
2057 }
2058 self.expect_field_ty_separator()?;
2059 let ty = self.parse_ty()?;
2060 if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2061 self.dcx()
2062 .struct_span_err(self.token.span, "found single colon in a struct field type path")
2063 .with_span_suggestion_verbose(
2064 self.token.span,
2065 "write a path separator here",
2066 "::",
2067 Applicability::MaybeIncorrect,
2068 )
2069 .emit();
2070 }
2071 let default = if self.token == token::Eq {
2072 self.bump();
2073 let const_expr = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?;
2074 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2075 self.psess.gated_spans.gate(sym::default_field_values, sp);
2076 Some(const_expr)
2077 } else {
2078 None
2079 };
2080 Ok(FieldDef {
2081 span: lo.to(self.prev_token.span),
2082 ident: Some(name),
2083 vis,
2084 safety,
2085 id: DUMMY_NODE_ID,
2086 ty,
2087 default,
2088 attrs,
2089 is_placeholder: false,
2090 })
2091 }
2092
2093 fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2096 let (ident, is_raw) = self.ident_or_err(true)?;
2097 if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
2098 let snapshot = self.create_snapshot_for_diagnostic();
2099 let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2100 let inherited_vis =
2101 Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
2102 let fn_parse_mode =
2104 FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
2105 match self.parse_fn(
2106 &mut AttrVec::new(),
2107 fn_parse_mode,
2108 lo,
2109 &inherited_vis,
2110 Case::Insensitive,
2111 ) {
2112 Ok(_) => {
2113 self.dcx().struct_span_err(
2114 lo.to(self.prev_token.span),
2115 format!("functions are not allowed in {adt_ty} definitions"),
2116 )
2117 .with_help(
2118 "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2119 )
2120 .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information")
2121 }
2122 Err(err) => {
2123 err.cancel();
2124 self.restore_snapshot(snapshot);
2125 self.expected_ident_found_err()
2126 }
2127 }
2128 } else if self.eat_keyword(exp!(Struct)) {
2129 match self.parse_item_struct() {
2130 Ok(item) => {
2131 let ItemKind::Struct(ident, ..) = item else { unreachable!() };
2132 self.dcx()
2133 .struct_span_err(
2134 lo.with_hi(ident.span.hi()),
2135 format!("structs are not allowed in {adt_ty} definitions"),
2136 )
2137 .with_help(
2138 "consider creating a new `struct` definition instead of nesting",
2139 )
2140 }
2141 Err(err) => {
2142 err.cancel();
2143 self.restore_snapshot(snapshot);
2144 self.expected_ident_found_err()
2145 }
2146 }
2147 } else {
2148 let mut err = self.expected_ident_found_err();
2149 if self.eat_keyword_noexpect(kw::Let)
2150 && let removal_span = self.prev_token.span.until(self.token.span)
2151 && let Ok(ident) = self
2152 .parse_ident_common(false)
2153 .map_err(|err| err.cancel())
2155 && self.token == TokenKind::Colon
2156 {
2157 err.span_suggestion(
2158 removal_span,
2159 "remove this `let` keyword",
2160 String::new(),
2161 Applicability::MachineApplicable,
2162 );
2163 err.note("the `let` keyword is not allowed in `struct` fields");
2164 err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
2165 err.emit();
2166 return Ok(ident);
2167 } else {
2168 self.restore_snapshot(snapshot);
2169 }
2170 err
2171 };
2172 return Err(err);
2173 }
2174 self.bump();
2175 Ok(ident)
2176 }
2177
2178 fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2186 let ident = self.parse_ident()?;
2187 let body = if self.check(exp!(OpenBrace)) {
2188 self.parse_delim_args()? } else if self.check(exp!(OpenParen)) {
2190 let params = self.parse_token_tree(); let pspan = params.span();
2192 if !self.check(exp!(OpenBrace)) {
2193 self.unexpected()?;
2194 }
2195 let body = self.parse_token_tree(); let bspan = body.span();
2198 let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); let tokens = TokenStream::new(vec![params, arrow, body]);
2200 let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2201 Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2202 } else {
2203 self.unexpected_any()?
2204 };
2205
2206 self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2207 Ok(ItemKind::MacroDef(
2208 ident,
2209 ast::MacroDef { body, macro_rules: false, eii_extern_target: None },
2210 ))
2211 }
2212
2213 fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2215 if self.check_keyword(exp!(MacroRules)) {
2216 let macro_rules_span = self.token.span;
2217
2218 if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2219 return IsMacroRulesItem::Yes { has_bang: true };
2220 } else if self.look_ahead(1, |t| t.is_ident()) {
2221 self.dcx().emit_err(errors::MacroRulesMissingBang {
2223 span: macro_rules_span,
2224 hi: macro_rules_span.shrink_to_hi(),
2225 });
2226
2227 return IsMacroRulesItem::Yes { has_bang: false };
2228 }
2229 }
2230
2231 IsMacroRulesItem::No
2232 }
2233
2234 fn parse_item_macro_rules(
2236 &mut self,
2237 vis: &Visibility,
2238 has_bang: bool,
2239 ) -> PResult<'a, ItemKind> {
2240 self.expect_keyword(exp!(MacroRules))?; if has_bang {
2243 self.expect(exp!(Bang))?; }
2245 let ident = self.parse_ident()?;
2246
2247 if self.eat(exp!(Bang)) {
2248 let span = self.prev_token.span;
2250 self.dcx().emit_err(errors::MacroNameRemoveBang { span });
2251 }
2252
2253 let body = self.parse_delim_args()?;
2254 self.eat_semi_for_macro_if_needed(&body);
2255 self.complain_if_pub_macro(vis, true);
2256
2257 Ok(ItemKind::MacroDef(
2258 ident,
2259 ast::MacroDef { body, macro_rules: true, eii_extern_target: None },
2260 ))
2261 }
2262
2263 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 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 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 return Ok(false);
2333 }
2334 Ok(true)
2335 }
2336}
2337
2338type ReqName = fn(Edition, IsDotDotDot) -> bool;
2347
2348#[derive(Copy, Clone, PartialEq)]
2349pub(crate) enum IsDotDotDot {
2350 Yes,
2351 No,
2352}
2353
2354#[derive(Clone, Copy)]
2362pub(crate) struct FnParseMode {
2363 pub(super) req_name: ReqName,
2389 pub(super) context: FnContext,
2392 pub(super) req_body: bool,
2411}
2412
2413#[derive(Clone, Copy, PartialEq, Eq)]
2416pub(crate) enum FnContext {
2417 Free,
2419 Trait,
2421 Impl,
2423}
2424
2425impl<'a> Parser<'a> {
2427 fn parse_fn(
2429 &mut self,
2430 attrs: &mut AttrVec,
2431 fn_parse_mode: FnParseMode,
2432 sig_lo: Span,
2433 vis: &Visibility,
2434 case: Case,
2435 ) -> PResult<'a, (Ident, FnSig, Generics, Option<Box<FnContract>>, Option<Box<Block>>)> {
2436 let fn_span = self.token.span;
2437 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(&fn_parse_mode, AllowPlus::Yes, RecoverReturnSign::Yes)
2441 {
2442 Ok(decl) => decl,
2443 Err(old_err) => {
2444 if self.token.is_keyword(kw::For) {
2446 old_err.cancel();
2447 return Err(self.dcx().create_err(errors::FnTypoWithImpl { fn_span }));
2448 } else {
2449 return Err(old_err);
2450 }
2451 }
2452 };
2453
2454 let fn_params_end = self.prev_token.span.shrink_to_hi();
2457
2458 let contract = self.parse_contract()?;
2459
2460 generics.where_clause = self.parse_where_clause()?; let fn_params_end =
2464 if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2465
2466 let mut sig_hi = self.prev_token.span;
2467 let body =
2469 self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
2470 let fn_sig_span = sig_lo.to(sig_hi);
2471 Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
2472 }
2473
2474 fn error_fn_body_not_found(
2476 &mut self,
2477 ident_span: Span,
2478 req_body: bool,
2479 fn_params_end: Option<Span>,
2480 ) -> PResult<'a, ErrorGuaranteed> {
2481 let expected: &[_] =
2482 if req_body { &[exp!(OpenBrace)] } else { &[exp!(Semi), exp!(OpenBrace)] };
2483 match self.expected_one_of_not_found(&[], expected) {
2484 Ok(error_guaranteed) => Ok(error_guaranteed),
2485 Err(mut err) => {
2486 if self.token == token::CloseBrace {
2487 err.span_label(ident_span, "while parsing this `fn`");
2490 Ok(err.emit())
2491 } else if self.token == token::RArrow
2492 && let Some(fn_params_end) = fn_params_end
2493 {
2494 let fn_trait_span =
2500 [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2501 if self.prev_token.is_ident_named(symbol) {
2502 Some(self.prev_token.span)
2503 } else {
2504 None
2505 }
2506 });
2507
2508 let arrow_span = self.token.span;
2513 let ty_span = match self.parse_ret_ty(
2514 AllowPlus::Yes,
2515 RecoverQPath::Yes,
2516 RecoverReturnSign::Yes,
2517 ) {
2518 Ok(ty_span) => ty_span.span().shrink_to_hi(),
2519 Err(parse_error) => {
2520 parse_error.cancel();
2521 return Err(err);
2522 }
2523 };
2524 let ret_ty_span = arrow_span.to(ty_span);
2525
2526 if let Some(fn_trait_span) = fn_trait_span {
2527 err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2530 } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2531 {
2532 err.primary_message(
2536 "return type should be specified after the function parameters",
2537 );
2538 err.subdiagnostic(errors::MisplacedReturnType {
2539 fn_params_end,
2540 snippet,
2541 ret_ty_span,
2542 });
2543 }
2544 Err(err)
2545 } else {
2546 Err(err)
2547 }
2548 }
2549 }
2550 }
2551
2552 fn parse_fn_body(
2556 &mut self,
2557 attrs: &mut AttrVec,
2558 ident: &Ident,
2559 sig_hi: &mut Span,
2560 req_body: bool,
2561 fn_params_end: Option<Span>,
2562 ) -> PResult<'a, Option<Box<Block>>> {
2563 let has_semi = if req_body {
2564 self.token == TokenKind::Semi
2565 } else {
2566 self.check(exp!(Semi))
2568 };
2569 let (inner_attrs, body) = if has_semi {
2570 self.expect_semi()?;
2572 *sig_hi = self.prev_token.span;
2573 (AttrVec::new(), None)
2574 } else if self.check(exp!(OpenBrace)) || self.token.is_metavar_block() {
2575 self.parse_block_common(self.token.span, BlockCheckMode::Default, None)
2576 .map(|(attrs, body)| (attrs, Some(body)))?
2577 } else if self.token == token::Eq {
2578 self.bump(); let eq_sp = self.prev_token.span;
2581 let _ = self.parse_expr()?;
2582 self.expect_semi()?; let span = eq_sp.to(self.prev_token.span);
2584 let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
2585 span,
2586 sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
2587 });
2588 (AttrVec::new(), Some(self.mk_block_err(span, guar)))
2589 } else {
2590 self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
2591 (AttrVec::new(), None)
2592 };
2593 attrs.extend(inner_attrs);
2594 Ok(body)
2595 }
2596
2597 fn check_impl_frontmatter(&mut self) -> bool {
2598 const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe];
2599 if self.check_keyword(exp!(Impl)) {
2602 return true;
2603 }
2604 let mut i = 0;
2605 while i < ALL_QUALS.len() {
2606 let action = self.look_ahead(i, |token| {
2607 if token.is_keyword(kw::Impl) {
2608 return Some(true);
2609 }
2610 if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
2611 return None;
2613 }
2614 Some(false)
2615 });
2616 if let Some(ret) = action {
2617 return ret;
2618 }
2619 i += 1;
2620 }
2621 self.is_keyword_ahead(i, &[kw::Impl])
2622 }
2623
2624 pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
2629 const ALL_QUALS: &[ExpKeywordPair] = &[
2630 exp!(Pub),
2631 exp!(Gen),
2632 exp!(Const),
2633 exp!(Async),
2634 exp!(Unsafe),
2635 exp!(Safe),
2636 exp!(Extern),
2637 ];
2638
2639 let quals: &[_] = if check_pub {
2644 ALL_QUALS
2645 } else {
2646 &[exp!(Gen), exp!(Const), exp!(Async), exp!(Unsafe), exp!(Safe), exp!(Extern)]
2647 };
2648 self.check_keyword_case(exp!(Fn), case) || quals.iter().any(|&exp| self.check_keyword_case(exp, case))
2651 && self.look_ahead(1, |t| {
2652 t.is_keyword_case(kw::Fn, case)
2654 || (
2656 (
2657 t.is_non_raw_ident_where(|i|
2658 quals.iter().any(|exp| exp.kw == i.name)
2659 && i.is_reserved()
2661 )
2662 || case == Case::Insensitive
2663 && t.is_non_raw_ident_where(|i| quals.iter().any(|exp| {
2664 exp.kw.as_str() == i.name.as_str().to_lowercase()
2665 }))
2666 )
2667 && !self.is_unsafe_foreign_mod()
2669 && !self.is_async_gen_block()
2671 && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait])
2673 )
2674 })
2675 || self.check_keyword_case(exp!(Extern), case)
2677 && self.look_ahead(1, |t| t.can_begin_string_literal())
2681 && (self.tree_look_ahead(2, |tt| {
2682 match tt {
2683 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2684 TokenTree::Delimited(..) => false,
2685 }
2686 }) == Some(true) ||
2687 (self.may_recover()
2690 && self.tree_look_ahead(2, |tt| {
2691 match tt {
2692 TokenTree::Token(t, _) =>
2693 ALL_QUALS.iter().any(|exp| {
2694 t.is_keyword(exp.kw)
2695 }),
2696 TokenTree::Delimited(..) => false,
2697 }
2698 }) == Some(true)
2699 && self.tree_look_ahead(3, |tt| {
2700 match tt {
2701 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2702 TokenTree::Delimited(..) => false,
2703 }
2704 }) == Some(true)
2705 )
2706 )
2707 }
2708
2709 pub(super) fn parse_fn_front_matter(
2724 &mut self,
2725 orig_vis: &Visibility,
2726 case: Case,
2727 parsing_mode: FrontMatterParsingMode,
2728 ) -> PResult<'a, FnHeader> {
2729 let sp_start = self.token.span;
2730 let constness = self.parse_constness(case);
2731 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2732 && let Const::Yes(const_span) = constness
2733 {
2734 self.dcx().emit_err(FnPointerCannotBeConst {
2735 span: const_span,
2736 suggestion: const_span.until(self.token.span),
2737 });
2738 }
2739
2740 let async_start_sp = self.token.span;
2741 let coroutine_kind = self.parse_coroutine_kind(case);
2742 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2743 && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind
2744 {
2745 self.dcx().emit_err(FnPointerCannotBeAsync {
2746 span: async_span,
2747 suggestion: async_span.until(self.token.span),
2748 });
2749 }
2750 let unsafe_start_sp = self.token.span;
2753 let safety = self.parse_safety(case);
2754
2755 let ext_start_sp = self.token.span;
2756 let ext = self.parse_extern(case);
2757
2758 if let Some(CoroutineKind::Async { span, .. }) = coroutine_kind {
2759 if span.is_rust_2015() {
2760 self.dcx().emit_err(errors::AsyncFnIn2015 {
2761 span,
2762 help: errors::HelpUseLatestEdition::new(),
2763 });
2764 }
2765 }
2766
2767 match coroutine_kind {
2768 Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
2769 self.psess.gated_spans.gate(sym::gen_blocks, span);
2770 }
2771 Some(CoroutineKind::Async { .. }) | None => {}
2772 }
2773
2774 if !self.eat_keyword_case(exp!(Fn), case) {
2775 match self.expect_one_of(&[], &[]) {
2779 Ok(Recovered::Yes(_)) => {}
2780 Ok(Recovered::No) => unreachable!(),
2781 Err(mut err) => {
2782 enum WrongKw {
2784 Duplicated(Span),
2785 Misplaced(Span),
2786 MisplacedDisallowedQualifier,
2791 }
2792
2793 let mut recover_constness = constness;
2795 let mut recover_coroutine_kind = coroutine_kind;
2796 let mut recover_safety = safety;
2797 let wrong_kw = if self.check_keyword(exp!(Const)) {
2800 match constness {
2801 Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
2802 Const::No => {
2803 recover_constness = Const::Yes(self.token.span);
2804 match parsing_mode {
2805 FrontMatterParsingMode::Function => {
2806 Some(WrongKw::Misplaced(async_start_sp))
2807 }
2808 FrontMatterParsingMode::FunctionPtrType => {
2809 self.dcx().emit_err(FnPointerCannotBeConst {
2810 span: self.token.span,
2811 suggestion: self
2812 .token
2813 .span
2814 .with_lo(self.prev_token.span.hi()),
2815 });
2816 Some(WrongKw::MisplacedDisallowedQualifier)
2817 }
2818 }
2819 }
2820 }
2821 } else if self.check_keyword(exp!(Async)) {
2822 match coroutine_kind {
2823 Some(CoroutineKind::Async { span, .. }) => {
2824 Some(WrongKw::Duplicated(span))
2825 }
2826 Some(CoroutineKind::AsyncGen { span, .. }) => {
2827 Some(WrongKw::Duplicated(span))
2828 }
2829 Some(CoroutineKind::Gen { .. }) => {
2830 recover_coroutine_kind = Some(CoroutineKind::AsyncGen {
2831 span: self.token.span,
2832 closure_id: DUMMY_NODE_ID,
2833 return_impl_trait_id: DUMMY_NODE_ID,
2834 });
2835 Some(WrongKw::Misplaced(unsafe_start_sp))
2837 }
2838 None => {
2839 recover_coroutine_kind = Some(CoroutineKind::Async {
2840 span: self.token.span,
2841 closure_id: DUMMY_NODE_ID,
2842 return_impl_trait_id: DUMMY_NODE_ID,
2843 });
2844 match parsing_mode {
2845 FrontMatterParsingMode::Function => {
2846 Some(WrongKw::Misplaced(async_start_sp))
2847 }
2848 FrontMatterParsingMode::FunctionPtrType => {
2849 self.dcx().emit_err(FnPointerCannotBeAsync {
2850 span: self.token.span,
2851 suggestion: self
2852 .token
2853 .span
2854 .with_lo(self.prev_token.span.hi()),
2855 });
2856 Some(WrongKw::MisplacedDisallowedQualifier)
2857 }
2858 }
2859 }
2860 }
2861 } else if self.check_keyword(exp!(Unsafe)) {
2862 match safety {
2863 Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
2864 Safety::Safe(sp) => {
2865 recover_safety = Safety::Unsafe(self.token.span);
2866 Some(WrongKw::Misplaced(sp))
2867 }
2868 Safety::Default => {
2869 recover_safety = Safety::Unsafe(self.token.span);
2870 Some(WrongKw::Misplaced(ext_start_sp))
2871 }
2872 }
2873 } else if self.check_keyword(exp!(Safe)) {
2874 match safety {
2875 Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
2876 Safety::Unsafe(sp) => {
2877 recover_safety = Safety::Safe(self.token.span);
2878 Some(WrongKw::Misplaced(sp))
2879 }
2880 Safety::Default => {
2881 recover_safety = Safety::Safe(self.token.span);
2882 Some(WrongKw::Misplaced(ext_start_sp))
2883 }
2884 }
2885 } else {
2886 None
2887 };
2888
2889 if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw {
2891 let original_kw = self
2892 .span_to_snippet(original_sp)
2893 .expect("Span extracted directly from keyword should always work");
2894
2895 err.span_suggestion(
2896 self.token_uninterpolated_span(),
2897 format!("`{original_kw}` already used earlier, remove this one"),
2898 "",
2899 Applicability::MachineApplicable,
2900 )
2901 .span_note(original_sp, format!("`{original_kw}` first seen here"));
2902 }
2903 else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
2905 let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
2906 if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
2907 let misplaced_qual_sp = self.token_uninterpolated_span();
2908 let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
2909
2910 err.span_suggestion(
2911 correct_pos_sp.to(misplaced_qual_sp),
2912 format!("`{misplaced_qual}` must come before `{current_qual}`"),
2913 format!("{misplaced_qual} {current_qual}"),
2914 Applicability::MachineApplicable,
2915 ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
2916 }
2917 }
2918 else if self.check_keyword(exp!(Pub)) {
2920 let sp = sp_start.to(self.prev_token.span);
2921 if let Ok(snippet) = self.span_to_snippet(sp) {
2922 let current_vis = match self.parse_visibility(FollowedByType::No) {
2923 Ok(v) => v,
2924 Err(d) => {
2925 d.cancel();
2926 return Err(err);
2927 }
2928 };
2929 let vs = pprust::vis_to_string(¤t_vis);
2930 let vs = vs.trim_end();
2931
2932 if matches!(orig_vis.kind, VisibilityKind::Inherited) {
2934 err.span_suggestion(
2935 sp_start.to(self.prev_token.span),
2936 format!("visibility `{vs}` must come before `{snippet}`"),
2937 format!("{vs} {snippet}"),
2938 Applicability::MachineApplicable,
2939 );
2940 }
2941 else {
2943 err.span_suggestion(
2944 current_vis.span,
2945 "there is already a visibility modifier, remove one",
2946 "",
2947 Applicability::MachineApplicable,
2948 )
2949 .span_note(orig_vis.span, "explicit visibility first seen here");
2950 }
2951 }
2952 }
2953
2954 if let Some(wrong_kw) = wrong_kw
2957 && self.may_recover()
2958 && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
2959 {
2960 self.bump();
2962 self.bump();
2963 if matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) {
2966 err.cancel();
2967 } else {
2968 err.emit();
2969 }
2970 return Ok(FnHeader {
2971 constness: recover_constness,
2972 safety: recover_safety,
2973 coroutine_kind: recover_coroutine_kind,
2974 ext,
2975 });
2976 }
2977
2978 return Err(err);
2979 }
2980 }
2981 }
2982
2983 Ok(FnHeader { constness, safety, coroutine_kind, ext })
2984 }
2985
2986 pub(super) fn parse_fn_decl(
2988 &mut self,
2989 fn_parse_mode: &FnParseMode,
2990 ret_allow_plus: AllowPlus,
2991 recover_return_sign: RecoverReturnSign,
2992 ) -> PResult<'a, Box<FnDecl>> {
2993 Ok(Box::new(FnDecl {
2994 inputs: self.parse_fn_params(fn_parse_mode)?,
2995 output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
2996 }))
2997 }
2998
2999 pub(super) fn parse_fn_params(
3001 &mut self,
3002 fn_parse_mode: &FnParseMode,
3003 ) -> PResult<'a, ThinVec<Param>> {
3004 let mut first_param = true;
3005 if self.token != TokenKind::OpenParen
3007 && !self.token.is_keyword(kw::For)
3009 {
3010 self.dcx()
3012 .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() });
3013 return Ok(ThinVec::new());
3014 }
3015
3016 let (mut params, _) = self.parse_paren_comma_seq(|p| {
3017 p.recover_vcs_conflict_marker();
3018 let snapshot = p.create_snapshot_for_diagnostic();
3019 let param = p.parse_param_general(fn_parse_mode, first_param, true).or_else(|e| {
3020 let guar = e.emit();
3021 let lo = if let TokenKind::OpenParen = p.prev_token.kind {
3025 p.prev_token.span.shrink_to_hi()
3026 } else {
3027 p.prev_token.span
3028 };
3029 p.restore_snapshot(snapshot);
3030 p.eat_to_tokens(&[exp!(Comma), exp!(CloseParen)]);
3032 Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
3034 });
3035 first_param = false;
3037 param
3038 })?;
3039 self.deduplicate_recovered_params_names(&mut params);
3041 Ok(params)
3042 }
3043
3044 pub(super) fn parse_param_general(
3049 &mut self,
3050 fn_parse_mode: &FnParseMode,
3051 first_param: bool,
3052 recover_arg_parse: bool,
3053 ) -> PResult<'a, Param> {
3054 let lo = self.token.span;
3055 let attrs = self.parse_outer_attributes()?;
3056 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
3057 if let Some(mut param) = this.parse_self_param()? {
3059 param.attrs = attrs;
3060 let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
3061 return Ok((res?, Trailing::No, UsePreAttrPos::No));
3062 }
3063
3064 let is_dot_dot_dot = if this.token.kind == token::DotDotDot {
3065 IsDotDotDot::Yes
3066 } else {
3067 IsDotDotDot::No
3068 };
3069 let is_name_required = (fn_parse_mode.req_name)(
3070 this.token.span.with_neighbor(this.prev_token.span).edition(),
3071 is_dot_dot_dot,
3072 );
3073 let is_name_required = if is_name_required && is_dot_dot_dot == IsDotDotDot::Yes {
3074 this.psess.buffer_lint(
3075 VARARGS_WITHOUT_PATTERN,
3076 this.token.span,
3077 ast::CRATE_NODE_ID,
3078 errors::VarargsWithoutPattern { span: this.token.span },
3079 );
3080 false
3081 } else {
3082 is_name_required
3083 };
3084 let (pat, ty) = if is_name_required || this.is_named_param() {
3085 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
3086 let (pat, colon) = this.parse_fn_param_pat_colon()?;
3087 if !colon {
3088 let mut err = this.unexpected().unwrap_err();
3089 return if let Some(ident) = this.parameter_without_type(
3090 &mut err,
3091 pat,
3092 is_name_required,
3093 first_param,
3094 fn_parse_mode,
3095 ) {
3096 let guar = err.emit();
3097 Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No))
3098 } else {
3099 Err(err)
3100 };
3101 }
3102
3103 this.eat_incorrect_doc_comment_for_param_type();
3104 (pat, this.parse_ty_for_param()?)
3105 } else {
3106 debug!("parse_param_general ident_to_pat");
3107 let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
3108 this.eat_incorrect_doc_comment_for_param_type();
3109 let mut ty = this.parse_ty_for_param();
3110
3111 if let Ok(t) = &ty {
3112 if let TyKind::Path(_, Path { segments, .. }) = &t.kind
3114 && let Some(segment) = segments.last()
3115 && let Some(guar) =
3116 this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
3117 {
3118 return Ok((
3119 dummy_arg(segment.ident, guar),
3120 Trailing::No,
3121 UsePreAttrPos::No,
3122 ));
3123 }
3124
3125 if this.token != token::Comma && this.token != token::CloseParen {
3126 ty = this.unexpected_any();
3129 }
3130 }
3131 match ty {
3132 Ok(ty) => {
3133 let pat = this.mk_pat(ty.span, PatKind::Missing);
3134 (Box::new(pat), ty)
3135 }
3136 Err(err) if this.token == token::DotDotDot => return Err(err),
3138 Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
3139 Err(err) if recover_arg_parse => {
3140 err.cancel();
3142 this.restore_snapshot(parser_snapshot_before_ty);
3143 this.recover_arg_parse()?
3144 }
3145 Err(err) => return Err(err),
3146 }
3147 };
3148
3149 let span = lo.to(this.prev_token.span);
3150
3151 Ok((
3152 Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
3153 Trailing::No,
3154 UsePreAttrPos::No,
3155 ))
3156 })
3157 }
3158
3159 fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
3161 let expect_self_ident = |this: &mut Self| match this.token.ident() {
3163 Some((ident, IdentIsRaw::No)) => {
3164 this.bump();
3165 ident
3166 }
3167 _ => unreachable!(),
3168 };
3169 let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
3171 let is_isolated_self = |this: &Self, n| {
3173 this.is_keyword_ahead(n, &[kw::SelfLower])
3174 && this.look_ahead(n + 1, |t| t != &token::PathSep)
3175 };
3176 let is_isolated_pin_const_self = |this: &Self, n| {
3178 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3179 && this.is_keyword_ahead(n + 1, &[kw::Const])
3180 && is_isolated_self(this, n + 2)
3181 };
3182 let is_isolated_mut_self =
3184 |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
3185 let is_isolated_pin_mut_self = |this: &Self, n| {
3187 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3188 && is_isolated_mut_self(this, n + 1)
3189 };
3190 let parse_self_possibly_typed = |this: &mut Self, m| {
3192 let eself_ident = expect_self_ident(this);
3193 let eself_hi = this.prev_token.span;
3194 let eself = if this.eat(exp!(Colon)) {
3195 SelfKind::Explicit(this.parse_ty()?, m)
3196 } else {
3197 SelfKind::Value(m)
3198 };
3199 Ok((eself, eself_ident, eself_hi))
3200 };
3201 let expect_self_ident_not_typed =
3202 |this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
3203 let eself_ident = expect_self_ident(this);
3204
3205 if this.may_recover() && this.eat_noexpect(&token::Colon) {
3207 let snap = this.create_snapshot_for_diagnostic();
3208 match this.parse_ty() {
3209 Ok(ty) => {
3210 this.dcx().emit_err(errors::IncorrectTypeOnSelf {
3211 span: ty.span,
3212 move_self_modifier: errors::MoveSelfModifier {
3213 removal_span: modifier_span,
3214 insertion_span: ty.span.shrink_to_lo(),
3215 modifier: modifier.to_ref_suggestion(),
3216 },
3217 });
3218 }
3219 Err(diag) => {
3220 diag.cancel();
3221 this.restore_snapshot(snap);
3222 }
3223 }
3224 }
3225 eself_ident
3226 };
3227 let recover_self_ptr = |this: &mut Self| {
3229 this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
3230
3231 Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
3232 };
3233
3234 let eself_lo = self.token.span;
3238 let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
3239 token::And => {
3240 let has_lifetime = is_lifetime(self, 1);
3241 let skip_lifetime_count = has_lifetime as usize;
3242 let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3243 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3246 SelfKind::Region(lifetime, Mutability::Not)
3247 } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3248 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3251 self.bump(); SelfKind::Region(lifetime, Mutability::Mut)
3253 } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3254 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3257 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3258 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Not)
3261 } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
3262 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3265 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3266 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Mut)
3269 } else {
3270 return Ok(None);
3272 };
3273 let hi = self.token.span;
3274 let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3275 (eself, self_ident, hi)
3276 }
3277 token::Star if is_isolated_self(self, 1) => {
3279 self.bump();
3280 recover_self_ptr(self)?
3281 }
3282 token::Star
3284 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
3285 {
3286 self.bump();
3287 self.bump();
3288 recover_self_ptr(self)?
3289 }
3290 token::Ident(..) if is_isolated_self(self, 0) => {
3292 parse_self_possibly_typed(self, Mutability::Not)?
3293 }
3294 token::Ident(..) if is_isolated_mut_self(self, 0) => {
3296 self.bump();
3297 parse_self_possibly_typed(self, Mutability::Mut)?
3298 }
3299 _ => return Ok(None),
3300 };
3301
3302 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
3303 Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
3304 }
3305
3306 fn is_named_param(&self) -> bool {
3307 let offset = match &self.token.kind {
3308 token::OpenInvisible(origin) => match origin {
3309 InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
3310 return self.check_noexpect_past_close_delim(&token::Colon);
3311 }
3312 _ => 0,
3313 },
3314 token::And | token::AndAnd => 1,
3315 _ if self.token.is_keyword(kw::Mut) => 1,
3316 _ => 0,
3317 };
3318
3319 self.look_ahead(offset, |t| t.is_ident())
3320 && self.look_ahead(offset + 1, |t| t == &token::Colon)
3321 }
3322
3323 fn recover_self_param(&mut self) -> bool {
3324 matches!(
3325 self.parse_outer_attributes()
3326 .and_then(|_| self.parse_self_param())
3327 .map_err(|e| e.cancel()),
3328 Ok(Some(_))
3329 )
3330 }
3331}
3332
3333enum IsMacroRulesItem {
3334 Yes { has_bang: bool },
3335 No,
3336}
3337
3338#[derive(Copy, Clone, PartialEq, Eq)]
3339pub(super) enum FrontMatterParsingMode {
3340 Function,
3342 FunctionPtrType,
3345}