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 }))
231 } else if self.eat_keyword_case(exp!(Extern), case) {
232 if self.eat_keyword_case(exp!(Crate), case) {
233 self.parse_item_extern_crate()?
235 } else {
236 self.parse_item_foreign_mod(attrs, Safety::Default)?
238 }
239 } else if self.is_unsafe_foreign_mod() {
240 let safety = self.parse_safety(Case::Sensitive);
242 self.expect_keyword(exp!(Extern))?;
243 self.parse_item_foreign_mod(attrs, safety)?
244 } else if let Some(safety) = self.parse_global_static_front_matter(case) {
245 let mutability = self.parse_mutability();
247 self.parse_static_item(safety, mutability)?
248 } else if self.check_keyword_case(exp!(Trait), case) || self.check_trait_front_matter() {
249 self.parse_item_trait(attrs, lo)?
251 } else if self.check_impl_frontmatter() {
252 self.parse_item_impl(attrs, def_())?
254 } else if let Const::Yes(const_span) = self.parse_constness(case) {
255 self.recover_const_mut(const_span);
257 self.recover_missing_kw_before_item()?;
258 let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?;
259 ItemKind::Const(Box::new(ConstItem {
260 defaultness: def_(),
261 ident,
262 generics,
263 ty,
264 rhs,
265 define_opaque: None,
266 }))
267 } else if self.is_reuse_path_item() {
268 self.parse_item_delegation()?
269 } else if self.check_keyword_case(exp!(Mod), case)
270 || self.check_keyword_case(exp!(Unsafe), case) && self.is_keyword_ahead(1, &[kw::Mod])
271 {
272 self.parse_item_mod(attrs)?
274 } else if self.eat_keyword_case(exp!(Type), case) {
275 self.parse_type_alias(def_())?
277 } else if self.eat_keyword_case(exp!(Enum), case) {
278 self.parse_item_enum()?
280 } else if self.eat_keyword_case(exp!(Struct), case) {
281 self.parse_item_struct()?
283 } else if self.is_kw_followed_by_ident(kw::Union) {
284 self.bump(); self.parse_item_union()?
287 } else if self.is_builtin() {
288 return self.parse_item_builtin();
290 } else if self.eat_keyword_case(exp!(Macro), case) {
291 self.parse_item_decl_macro(lo)?
293 } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() {
294 self.parse_item_macro_rules(vis, has_bang)?
296 } else if self.isnt_macro_invocation()
297 && (self.token.is_ident_named(sym::import)
298 || self.token.is_ident_named(sym::using)
299 || self.token.is_ident_named(sym::include)
300 || self.token.is_ident_named(sym::require))
301 {
302 return self.recover_import_as_use();
303 } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
304 self.recover_missing_kw_before_item()?;
305 return Ok(None);
306 } else if self.isnt_macro_invocation() && case == Case::Sensitive {
307 _ = def_;
308
309 return self.parse_item_kind(
311 attrs,
312 macros_allowed,
313 lo,
314 vis,
315 def,
316 fn_parse_mode,
317 Case::Insensitive,
318 );
319 } else if macros_allowed && self.check_path() {
320 if self.isnt_macro_invocation() {
321 self.recover_missing_kw_before_item()?;
322 }
323 ItemKind::MacCall(Box::new(self.parse_item_macro(vis)?))
325 } else {
326 return Ok(None);
327 };
328 Ok(Some(info))
329 }
330
331 fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
332 let span = self.token.span;
333 let token_name = super::token_descr(&self.token);
334 let snapshot = self.create_snapshot_for_diagnostic();
335 self.bump();
336 match self.parse_use_item() {
337 Ok(u) => {
338 self.dcx().emit_err(errors::RecoverImportAsUse { span, token_name });
339 Ok(Some(u))
340 }
341 Err(e) => {
342 e.cancel();
343 self.restore_snapshot(snapshot);
344 Ok(None)
345 }
346 }
347 }
348
349 fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
350 let tree = self.parse_use_tree()?;
351 if let Err(mut e) = self.expect_semi() {
352 match tree.kind {
353 UseTreeKind::Glob => {
354 e.note("the wildcard token must be last on the path");
355 }
356 UseTreeKind::Nested { .. } => {
357 e.note("glob-like brace syntax must be last on the path");
358 }
359 _ => (),
360 }
361 return Err(e);
362 }
363 Ok(ItemKind::Use(tree))
364 }
365
366 pub(super) fn is_path_start_item(&mut self) -> bool {
368 self.is_kw_followed_by_ident(kw::Union) || self.is_reuse_path_item()
370 || self.check_trait_front_matter() || self.is_async_fn() || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) }
374
375 fn is_reuse_path_item(&mut self) -> bool {
376 self.token.is_keyword(kw::Reuse)
378 && self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep)
379 }
380
381 fn isnt_macro_invocation(&mut self) -> bool {
383 self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep)
384 }
385
386 fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
389 let is_pub = self.prev_token.is_keyword(kw::Pub);
390 let is_const = self.prev_token.is_keyword(kw::Const);
391 let ident_span = self.token.span;
392 let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span };
393 let insert_span = ident_span.shrink_to_lo();
394
395 let ident = if self.token.is_ident()
396 && self.token.is_non_reserved_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_expr_anon_const()?))
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 =
1655 if this.eat(exp!(Eq)) { Some(this.parse_expr_anon_const()?) } else { None };
1656
1657 let vr = ast::Variant {
1658 ident,
1659 vis,
1660 id: DUMMY_NODE_ID,
1661 attrs: variant_attrs,
1662 data: struct_def,
1663 disr_expr,
1664 span: vlo.to(this.prev_token.span),
1665 is_placeholder: false,
1666 };
1667
1668 Ok((Some(vr), Trailing::from(this.token == token::Comma), UsePreAttrPos::No))
1669 })
1670 .map_err(|mut err| {
1671 err.help(help);
1672 err
1673 })
1674 }
1675
1676 fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
1678 let ident = self.parse_ident()?;
1679
1680 let mut generics = self.parse_generics()?;
1681
1682 let vdata = if self.token.is_keyword(kw::Where) {
1697 let tuple_struct_body;
1698 (generics.where_clause, tuple_struct_body) =
1699 self.parse_struct_where_clause(ident, generics.span)?;
1700
1701 if let Some(body) = tuple_struct_body {
1702 let body = VariantData::Tuple(body, DUMMY_NODE_ID);
1704 self.expect_semi()?;
1705 body
1706 } else if self.eat(exp!(Semi)) {
1707 VariantData::Unit(DUMMY_NODE_ID)
1709 } else {
1710 let (fields, recovered) = self.parse_record_struct_body(
1712 "struct",
1713 ident.span,
1714 generics.where_clause.has_where_token,
1715 )?;
1716 VariantData::Struct { fields, recovered }
1717 }
1718 } else if self.eat(exp!(Semi)) {
1720 VariantData::Unit(DUMMY_NODE_ID)
1721 } else if self.token == token::OpenBrace {
1723 let (fields, recovered) = self.parse_record_struct_body(
1724 "struct",
1725 ident.span,
1726 generics.where_clause.has_where_token,
1727 )?;
1728 VariantData::Struct { fields, recovered }
1729 } else if self.token == token::OpenParen {
1731 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1732 generics.where_clause = self.parse_where_clause()?;
1733 self.expect_semi()?;
1734 body
1735 } else {
1736 let err = errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token);
1737 return Err(self.dcx().create_err(err));
1738 };
1739
1740 Ok(ItemKind::Struct(ident, generics, vdata))
1741 }
1742
1743 fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
1745 let ident = self.parse_ident()?;
1746
1747 let mut generics = self.parse_generics()?;
1748
1749 let vdata = if self.token.is_keyword(kw::Where) {
1750 generics.where_clause = self.parse_where_clause()?;
1751 let (fields, recovered) = self.parse_record_struct_body(
1752 "union",
1753 ident.span,
1754 generics.where_clause.has_where_token,
1755 )?;
1756 VariantData::Struct { fields, recovered }
1757 } else if self.token == token::OpenBrace {
1758 let (fields, recovered) = self.parse_record_struct_body(
1759 "union",
1760 ident.span,
1761 generics.where_clause.has_where_token,
1762 )?;
1763 VariantData::Struct { fields, recovered }
1764 } else {
1765 let token_str = super::token_descr(&self.token);
1766 let msg = format!("expected `where` or `{{` after union name, found {token_str}");
1767 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1768 err.span_label(self.token.span, "expected `where` or `{` after union name");
1769 return Err(err);
1770 };
1771
1772 Ok(ItemKind::Union(ident, generics, vdata))
1773 }
1774
1775 pub(crate) fn parse_record_struct_body(
1780 &mut self,
1781 adt_ty: &str,
1782 ident_span: Span,
1783 parsed_where: bool,
1784 ) -> PResult<'a, (ThinVec<FieldDef>, Recovered)> {
1785 let mut fields = ThinVec::new();
1786 let mut recovered = Recovered::No;
1787 if self.eat(exp!(OpenBrace)) {
1788 while self.token != token::CloseBrace {
1789 match self.parse_field_def(adt_ty, ident_span) {
1790 Ok(field) => {
1791 fields.push(field);
1792 }
1793 Err(mut err) => {
1794 self.consume_block(
1795 exp!(OpenBrace),
1796 exp!(CloseBrace),
1797 ConsumeClosingDelim::No,
1798 );
1799 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1800 let guar = err.emit();
1801 recovered = Recovered::Yes(guar);
1802 break;
1803 }
1804 }
1805 }
1806 self.expect(exp!(CloseBrace))?;
1807 } else {
1808 let token_str = super::token_descr(&self.token);
1809 let where_str = if parsed_where { "" } else { "`where`, or " };
1810 let msg = format!("expected {where_str}`{{` after struct name, found {token_str}");
1811 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1812 err.span_label(self.token.span, format!("expected {where_str}`{{` after struct name",));
1813 return Err(err);
1814 }
1815
1816 Ok((fields, recovered))
1817 }
1818
1819 fn parse_unsafe_field(&mut self) -> Safety {
1820 if self.eat_keyword(exp!(Unsafe)) {
1822 let span = self.prev_token.span;
1823 self.psess.gated_spans.gate(sym::unsafe_fields, span);
1824 Safety::Unsafe(span)
1825 } else {
1826 Safety::Default
1827 }
1828 }
1829
1830 pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
1831 self.parse_paren_comma_seq(|p| {
1834 let attrs = p.parse_outer_attributes()?;
1835 p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
1836 let mut snapshot = None;
1837 if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
1838 snapshot = Some(p.create_snapshot_for_diagnostic());
1842 }
1843 let lo = p.token.span;
1844 let vis = match p.parse_visibility(FollowedByType::Yes) {
1845 Ok(vis) => vis,
1846 Err(err) => {
1847 if let Some(ref mut snapshot) = snapshot {
1848 snapshot.recover_vcs_conflict_marker();
1849 }
1850 return Err(err);
1851 }
1852 };
1853 let ty = match p.parse_ty() {
1856 Ok(ty) => ty,
1857 Err(err) => {
1858 if let Some(ref mut snapshot) = snapshot {
1859 snapshot.recover_vcs_conflict_marker();
1860 }
1861 return Err(err);
1862 }
1863 };
1864 let mut default = None;
1865 if p.token == token::Eq {
1866 let mut snapshot = p.create_snapshot_for_diagnostic();
1867 snapshot.bump();
1868 match snapshot.parse_expr_anon_const() {
1869 Ok(const_expr) => {
1870 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
1871 p.psess.gated_spans.gate(sym::default_field_values, sp);
1872 p.restore_snapshot(snapshot);
1873 default = Some(const_expr);
1874 }
1875 Err(err) => {
1876 err.cancel();
1877 }
1878 }
1879 }
1880
1881 Ok((
1882 FieldDef {
1883 span: lo.to(ty.span),
1884 vis,
1885 safety: Safety::Default,
1886 ident: None,
1887 id: DUMMY_NODE_ID,
1888 ty,
1889 default,
1890 attrs,
1891 is_placeholder: false,
1892 },
1893 Trailing::from(p.token == token::Comma),
1894 UsePreAttrPos::No,
1895 ))
1896 })
1897 })
1898 .map(|(r, _)| r)
1899 }
1900
1901 fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
1903 self.recover_vcs_conflict_marker();
1904 let attrs = self.parse_outer_attributes()?;
1905 self.recover_vcs_conflict_marker();
1906 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
1907 let lo = this.token.span;
1908 let vis = this.parse_visibility(FollowedByType::No)?;
1909 let safety = this.parse_unsafe_field();
1910 this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
1911 .map(|field| (field, Trailing::No, UsePreAttrPos::No))
1912 })
1913 }
1914
1915 fn parse_single_struct_field(
1917 &mut self,
1918 adt_ty: &str,
1919 lo: Span,
1920 vis: Visibility,
1921 safety: Safety,
1922 attrs: AttrVec,
1923 ident_span: Span,
1924 ) -> PResult<'a, FieldDef> {
1925 let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
1926 match self.token.kind {
1927 token::Comma => {
1928 self.bump();
1929 }
1930 token::Semi => {
1931 self.bump();
1932 let sp = self.prev_token.span;
1933 let mut err =
1934 self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
1935 err.span_suggestion_short(
1936 sp,
1937 "replace `;` with `,`",
1938 ",",
1939 Applicability::MachineApplicable,
1940 );
1941 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1942 err.emit();
1943 }
1944 token::CloseBrace => {}
1945 token::DocComment(..) => {
1946 let previous_span = self.prev_token.span;
1947 let mut err = errors::DocCommentDoesNotDocumentAnything {
1948 span: self.token.span,
1949 missing_comma: None,
1950 };
1951 self.bump(); if self.eat(exp!(Comma)) || self.token == token::CloseBrace {
1953 self.dcx().emit_err(err);
1954 } else {
1955 let sp = previous_span.shrink_to_hi();
1956 err.missing_comma = Some(sp);
1957 return Err(self.dcx().create_err(err));
1958 }
1959 }
1960 _ => {
1961 let sp = self.prev_token.span.shrink_to_hi();
1962 let msg =
1963 format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
1964
1965 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
1967 && let Some(last_segment) = segments.last()
1968 {
1969 let guar = self.check_trailing_angle_brackets(
1970 last_segment,
1971 &[exp!(Comma), exp!(CloseBrace)],
1972 );
1973 if let Some(_guar) = guar {
1974 let _ = self.eat(exp!(Comma));
1977
1978 return Ok(a_var);
1981 }
1982 }
1983
1984 let mut err = self.dcx().struct_span_err(sp, msg);
1985
1986 if self.token.is_ident()
1987 || (self.token == TokenKind::Pound
1988 && (self.look_ahead(1, |t| t == &token::OpenBracket)))
1989 {
1990 err.span_suggestion(
1993 sp,
1994 "try adding a comma",
1995 ",",
1996 Applicability::MachineApplicable,
1997 );
1998 err.emit();
1999 } else {
2000 return Err(err);
2001 }
2002 }
2003 }
2004 Ok(a_var)
2005 }
2006
2007 fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2008 if let Err(err) = self.expect(exp!(Colon)) {
2009 let sm = self.psess.source_map();
2010 let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2011 let semi_typo = self.token == token::Semi
2012 && self.look_ahead(1, |t| {
2013 t.is_path_start()
2014 && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2017 (Ok(l), Ok(r)) => l.line == r.line,
2018 _ => true,
2019 }
2020 });
2021 if eq_typo || semi_typo {
2022 self.bump();
2023 err.with_span_suggestion_short(
2025 self.prev_token.span,
2026 "field names and their types are separated with `:`",
2027 ":",
2028 Applicability::MachineApplicable,
2029 )
2030 .emit();
2031 } else {
2032 return Err(err);
2033 }
2034 }
2035 Ok(())
2036 }
2037
2038 fn parse_name_and_ty(
2040 &mut self,
2041 adt_ty: &str,
2042 lo: Span,
2043 vis: Visibility,
2044 safety: Safety,
2045 attrs: AttrVec,
2046 ) -> PResult<'a, FieldDef> {
2047 let name = self.parse_field_ident(adt_ty, lo)?;
2048 if self.token == token::Bang {
2049 if let Err(mut err) = self.unexpected() {
2050 err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2052 return Err(err);
2053 }
2054 }
2055 self.expect_field_ty_separator()?;
2056 let ty = self.parse_ty()?;
2057 if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2058 self.dcx()
2059 .struct_span_err(self.token.span, "found single colon in a struct field type path")
2060 .with_span_suggestion_verbose(
2061 self.token.span,
2062 "write a path separator here",
2063 "::",
2064 Applicability::MaybeIncorrect,
2065 )
2066 .emit();
2067 }
2068 let default = if self.token == token::Eq {
2069 self.bump();
2070 let const_expr = self.parse_expr_anon_const()?;
2071 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2072 self.psess.gated_spans.gate(sym::default_field_values, sp);
2073 Some(const_expr)
2074 } else {
2075 None
2076 };
2077 Ok(FieldDef {
2078 span: lo.to(self.prev_token.span),
2079 ident: Some(name),
2080 vis,
2081 safety,
2082 id: DUMMY_NODE_ID,
2083 ty,
2084 default,
2085 attrs,
2086 is_placeholder: false,
2087 })
2088 }
2089
2090 fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2093 let (ident, is_raw) = self.ident_or_err(true)?;
2094 if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
2095 let snapshot = self.create_snapshot_for_diagnostic();
2096 let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2097 let inherited_vis =
2098 Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
2099 let fn_parse_mode =
2101 FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
2102 match self.parse_fn(
2103 &mut AttrVec::new(),
2104 fn_parse_mode,
2105 lo,
2106 &inherited_vis,
2107 Case::Insensitive,
2108 ) {
2109 Ok(_) => {
2110 self.dcx().struct_span_err(
2111 lo.to(self.prev_token.span),
2112 format!("functions are not allowed in {adt_ty} definitions"),
2113 )
2114 .with_help(
2115 "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2116 )
2117 .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information")
2118 }
2119 Err(err) => {
2120 err.cancel();
2121 self.restore_snapshot(snapshot);
2122 self.expected_ident_found_err()
2123 }
2124 }
2125 } else if self.eat_keyword(exp!(Struct)) {
2126 match self.parse_item_struct() {
2127 Ok(item) => {
2128 let ItemKind::Struct(ident, ..) = item else { unreachable!() };
2129 self.dcx()
2130 .struct_span_err(
2131 lo.with_hi(ident.span.hi()),
2132 format!("structs are not allowed in {adt_ty} definitions"),
2133 )
2134 .with_help(
2135 "consider creating a new `struct` definition instead of nesting",
2136 )
2137 }
2138 Err(err) => {
2139 err.cancel();
2140 self.restore_snapshot(snapshot);
2141 self.expected_ident_found_err()
2142 }
2143 }
2144 } else {
2145 let mut err = self.expected_ident_found_err();
2146 if self.eat_keyword_noexpect(kw::Let)
2147 && let removal_span = self.prev_token.span.until(self.token.span)
2148 && let Ok(ident) = self
2149 .parse_ident_common(false)
2150 .map_err(|err| err.cancel())
2152 && self.token == TokenKind::Colon
2153 {
2154 err.span_suggestion(
2155 removal_span,
2156 "remove this `let` keyword",
2157 String::new(),
2158 Applicability::MachineApplicable,
2159 );
2160 err.note("the `let` keyword is not allowed in `struct` fields");
2161 err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
2162 err.emit();
2163 return Ok(ident);
2164 } else {
2165 self.restore_snapshot(snapshot);
2166 }
2167 err
2168 };
2169 return Err(err);
2170 }
2171 self.bump();
2172 Ok(ident)
2173 }
2174
2175 fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2183 let ident = self.parse_ident()?;
2184 let body = if self.check(exp!(OpenBrace)) {
2185 self.parse_delim_args()? } else if self.check(exp!(OpenParen)) {
2187 let params = self.parse_token_tree(); let pspan = params.span();
2189 if !self.check(exp!(OpenBrace)) {
2190 self.unexpected()?;
2191 }
2192 let body = self.parse_token_tree(); let bspan = body.span();
2195 let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); let tokens = TokenStream::new(vec![params, arrow, body]);
2197 let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2198 Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2199 } else {
2200 self.unexpected_any()?
2201 };
2202
2203 self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2204 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false }))
2205 }
2206
2207 fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2209 if self.check_keyword(exp!(MacroRules)) {
2210 let macro_rules_span = self.token.span;
2211
2212 if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2213 return IsMacroRulesItem::Yes { has_bang: true };
2214 } else if self.look_ahead(1, |t| t.is_ident()) {
2215 self.dcx().emit_err(errors::MacroRulesMissingBang {
2217 span: macro_rules_span,
2218 hi: macro_rules_span.shrink_to_hi(),
2219 });
2220
2221 return IsMacroRulesItem::Yes { has_bang: false };
2222 }
2223 }
2224
2225 IsMacroRulesItem::No
2226 }
2227
2228 fn parse_item_macro_rules(
2230 &mut self,
2231 vis: &Visibility,
2232 has_bang: bool,
2233 ) -> PResult<'a, ItemKind> {
2234 self.expect_keyword(exp!(MacroRules))?; if has_bang {
2237 self.expect(exp!(Bang))?; }
2239 let ident = self.parse_ident()?;
2240
2241 if self.eat(exp!(Bang)) {
2242 let span = self.prev_token.span;
2244 self.dcx().emit_err(errors::MacroNameRemoveBang { span });
2245 }
2246
2247 let body = self.parse_delim_args()?;
2248 self.eat_semi_for_macro_if_needed(&body);
2249 self.complain_if_pub_macro(vis, true);
2250
2251 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true }))
2252 }
2253
2254 fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
2257 if let VisibilityKind::Inherited = vis.kind {
2258 return;
2259 }
2260
2261 let vstr = pprust::vis_to_string(vis);
2262 let vstr = vstr.trim_end();
2263 if macro_rules {
2264 self.dcx().emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
2265 } else {
2266 self.dcx().emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
2267 }
2268 }
2269
2270 fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) {
2271 if args.need_semicolon() && !self.eat(exp!(Semi)) {
2272 self.report_invalid_macro_expansion_item(args);
2273 }
2274 }
2275
2276 fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) {
2277 let span = args.dspan.entire();
2278 let mut err = self.dcx().struct_span_err(
2279 span,
2280 "macros that expand to items must be delimited with braces or followed by a semicolon",
2281 );
2282 if !span.from_expansion() {
2285 let DelimSpan { open, close } = args.dspan;
2286 err.multipart_suggestion(
2287 "change the delimiters to curly braces",
2288 vec![(open, "{".to_string()), (close, '}'.to_string())],
2289 Applicability::MaybeIncorrect,
2290 );
2291 err.span_suggestion(
2292 span.with_neighbor(self.token.span).shrink_to_hi(),
2293 "add a semicolon",
2294 ';',
2295 Applicability::MaybeIncorrect,
2296 );
2297 }
2298 err.emit();
2299 }
2300
2301 fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
2304 if (self.token.is_keyword(kw::Enum)
2305 || self.token.is_keyword(kw::Struct)
2306 || self.token.is_keyword(kw::Union))
2307 && self.look_ahead(1, |t| t.is_ident())
2308 {
2309 let kw_token = self.token;
2310 let kw_str = pprust::token_to_string(&kw_token);
2311 let item = self.parse_item(ForceCollect::No)?;
2312 let mut item = item.unwrap().span;
2313 if self.token == token::Comma {
2314 item = item.to(self.token.span);
2315 }
2316 self.dcx().emit_err(errors::NestedAdt {
2317 span: kw_token.span,
2318 item,
2319 kw_str,
2320 keyword: keyword.as_str(),
2321 });
2322 return Ok(false);
2324 }
2325 Ok(true)
2326 }
2327}
2328
2329type ReqName = fn(Edition, IsDotDotDot) -> bool;
2338
2339#[derive(Copy, Clone, PartialEq)]
2340pub(crate) enum IsDotDotDot {
2341 Yes,
2342 No,
2343}
2344
2345#[derive(Clone, Copy)]
2353pub(crate) struct FnParseMode {
2354 pub(super) req_name: ReqName,
2380 pub(super) context: FnContext,
2383 pub(super) req_body: bool,
2402}
2403
2404#[derive(Clone, Copy, PartialEq, Eq)]
2407pub(crate) enum FnContext {
2408 Free,
2410 Trait,
2412 Impl,
2414}
2415
2416impl<'a> Parser<'a> {
2418 fn parse_fn(
2420 &mut self,
2421 attrs: &mut AttrVec,
2422 fn_parse_mode: FnParseMode,
2423 sig_lo: Span,
2424 vis: &Visibility,
2425 case: Case,
2426 ) -> PResult<'a, (Ident, FnSig, Generics, Option<Box<FnContract>>, Option<Box<Block>>)> {
2427 let fn_span = self.token.span;
2428 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)
2432 {
2433 Ok(decl) => decl,
2434 Err(old_err) => {
2435 if self.token.is_keyword(kw::For) {
2437 old_err.cancel();
2438 return Err(self.dcx().create_err(errors::FnTypoWithImpl { fn_span }));
2439 } else {
2440 return Err(old_err);
2441 }
2442 }
2443 };
2444
2445 let fn_params_end = self.prev_token.span.shrink_to_hi();
2448
2449 let contract = self.parse_contract()?;
2450
2451 generics.where_clause = self.parse_where_clause()?; let fn_params_end =
2455 if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2456
2457 let mut sig_hi = self.prev_token.span;
2458 let body =
2460 self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
2461 let fn_sig_span = sig_lo.to(sig_hi);
2462 Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
2463 }
2464
2465 fn error_fn_body_not_found(
2467 &mut self,
2468 ident_span: Span,
2469 req_body: bool,
2470 fn_params_end: Option<Span>,
2471 ) -> PResult<'a, ErrorGuaranteed> {
2472 let expected: &[_] =
2473 if req_body { &[exp!(OpenBrace)] } else { &[exp!(Semi), exp!(OpenBrace)] };
2474 match self.expected_one_of_not_found(&[], expected) {
2475 Ok(error_guaranteed) => Ok(error_guaranteed),
2476 Err(mut err) => {
2477 if self.token == token::CloseBrace {
2478 err.span_label(ident_span, "while parsing this `fn`");
2481 Ok(err.emit())
2482 } else if self.token == token::RArrow
2483 && let Some(fn_params_end) = fn_params_end
2484 {
2485 let fn_trait_span =
2491 [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2492 if self.prev_token.is_ident_named(symbol) {
2493 Some(self.prev_token.span)
2494 } else {
2495 None
2496 }
2497 });
2498
2499 let arrow_span = self.token.span;
2504 let ty_span = match self.parse_ret_ty(
2505 AllowPlus::Yes,
2506 RecoverQPath::Yes,
2507 RecoverReturnSign::Yes,
2508 ) {
2509 Ok(ty_span) => ty_span.span().shrink_to_hi(),
2510 Err(parse_error) => {
2511 parse_error.cancel();
2512 return Err(err);
2513 }
2514 };
2515 let ret_ty_span = arrow_span.to(ty_span);
2516
2517 if let Some(fn_trait_span) = fn_trait_span {
2518 err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2521 } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2522 {
2523 err.primary_message(
2527 "return type should be specified after the function parameters",
2528 );
2529 err.subdiagnostic(errors::MisplacedReturnType {
2530 fn_params_end,
2531 snippet,
2532 ret_ty_span,
2533 });
2534 }
2535 Err(err)
2536 } else {
2537 Err(err)
2538 }
2539 }
2540 }
2541 }
2542
2543 fn parse_fn_body(
2547 &mut self,
2548 attrs: &mut AttrVec,
2549 ident: &Ident,
2550 sig_hi: &mut Span,
2551 req_body: bool,
2552 fn_params_end: Option<Span>,
2553 ) -> PResult<'a, Option<Box<Block>>> {
2554 let has_semi = if req_body {
2555 self.token == TokenKind::Semi
2556 } else {
2557 self.check(exp!(Semi))
2559 };
2560 let (inner_attrs, body) = if has_semi {
2561 self.expect_semi()?;
2563 *sig_hi = self.prev_token.span;
2564 (AttrVec::new(), None)
2565 } else if self.check(exp!(OpenBrace)) || self.token.is_metavar_block() {
2566 self.parse_block_common(self.token.span, BlockCheckMode::Default, None)
2567 .map(|(attrs, body)| (attrs, Some(body)))?
2568 } else if self.token == token::Eq {
2569 self.bump(); let eq_sp = self.prev_token.span;
2572 let _ = self.parse_expr()?;
2573 self.expect_semi()?; let span = eq_sp.to(self.prev_token.span);
2575 let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
2576 span,
2577 sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
2578 });
2579 (AttrVec::new(), Some(self.mk_block_err(span, guar)))
2580 } else {
2581 self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
2582 (AttrVec::new(), None)
2583 };
2584 attrs.extend(inner_attrs);
2585 Ok(body)
2586 }
2587
2588 fn check_impl_frontmatter(&mut self) -> bool {
2589 const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe];
2590 if self.check_keyword(exp!(Impl)) {
2593 return true;
2594 }
2595 let mut i = 0;
2596 while i < ALL_QUALS.len() {
2597 let action = self.look_ahead(i, |token| {
2598 if token.is_keyword(kw::Impl) {
2599 return Some(true);
2600 }
2601 if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
2602 return None;
2604 }
2605 Some(false)
2606 });
2607 if let Some(ret) = action {
2608 return ret;
2609 }
2610 i += 1;
2611 }
2612 self.is_keyword_ahead(i, &[kw::Impl])
2613 }
2614
2615 pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
2620 const ALL_QUALS: &[ExpKeywordPair] = &[
2621 exp!(Pub),
2622 exp!(Gen),
2623 exp!(Const),
2624 exp!(Async),
2625 exp!(Unsafe),
2626 exp!(Safe),
2627 exp!(Extern),
2628 ];
2629
2630 let quals: &[_] = if check_pub {
2635 ALL_QUALS
2636 } else {
2637 &[exp!(Gen), exp!(Const), exp!(Async), exp!(Unsafe), exp!(Safe), exp!(Extern)]
2638 };
2639 self.check_keyword_case(exp!(Fn), case) || quals.iter().any(|&exp| self.check_keyword_case(exp, case))
2642 && self.look_ahead(1, |t| {
2643 t.is_keyword_case(kw::Fn, case)
2645 || (
2647 (
2648 t.is_non_raw_ident_where(|i|
2649 quals.iter().any(|exp| exp.kw == i.name)
2650 && i.is_reserved()
2652 )
2653 || case == Case::Insensitive
2654 && t.is_non_raw_ident_where(|i| quals.iter().any(|exp| {
2655 exp.kw.as_str() == i.name.as_str().to_lowercase()
2656 }))
2657 )
2658 && !self.is_unsafe_foreign_mod()
2660 && !self.is_async_gen_block()
2662 && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait])
2664 )
2665 })
2666 || self.check_keyword_case(exp!(Extern), case)
2668 && self.look_ahead(1, |t| t.can_begin_string_literal())
2672 && (self.tree_look_ahead(2, |tt| {
2673 match tt {
2674 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2675 TokenTree::Delimited(..) => false,
2676 }
2677 }) == Some(true) ||
2678 (self.may_recover()
2681 && self.tree_look_ahead(2, |tt| {
2682 match tt {
2683 TokenTree::Token(t, _) =>
2684 ALL_QUALS.iter().any(|exp| {
2685 t.is_keyword(exp.kw)
2686 }),
2687 TokenTree::Delimited(..) => false,
2688 }
2689 }) == Some(true)
2690 && self.tree_look_ahead(3, |tt| {
2691 match tt {
2692 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2693 TokenTree::Delimited(..) => false,
2694 }
2695 }) == Some(true)
2696 )
2697 )
2698 }
2699
2700 pub(super) fn parse_fn_front_matter(
2715 &mut self,
2716 orig_vis: &Visibility,
2717 case: Case,
2718 parsing_mode: FrontMatterParsingMode,
2719 ) -> PResult<'a, FnHeader> {
2720 let sp_start = self.token.span;
2721 let constness = self.parse_constness(case);
2722 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2723 && let Const::Yes(const_span) = constness
2724 {
2725 self.dcx().emit_err(FnPointerCannotBeConst {
2726 span: const_span,
2727 suggestion: const_span.until(self.token.span),
2728 });
2729 }
2730
2731 let async_start_sp = self.token.span;
2732 let coroutine_kind = self.parse_coroutine_kind(case);
2733 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2734 && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind
2735 {
2736 self.dcx().emit_err(FnPointerCannotBeAsync {
2737 span: async_span,
2738 suggestion: async_span.until(self.token.span),
2739 });
2740 }
2741 let unsafe_start_sp = self.token.span;
2744 let safety = self.parse_safety(case);
2745
2746 let ext_start_sp = self.token.span;
2747 let ext = self.parse_extern(case);
2748
2749 if let Some(CoroutineKind::Async { span, .. }) = coroutine_kind {
2750 if span.is_rust_2015() {
2751 self.dcx().emit_err(errors::AsyncFnIn2015 {
2752 span,
2753 help: errors::HelpUseLatestEdition::new(),
2754 });
2755 }
2756 }
2757
2758 match coroutine_kind {
2759 Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
2760 self.psess.gated_spans.gate(sym::gen_blocks, span);
2761 }
2762 Some(CoroutineKind::Async { .. }) | None => {}
2763 }
2764
2765 if !self.eat_keyword_case(exp!(Fn), case) {
2766 match self.expect_one_of(&[], &[]) {
2770 Ok(Recovered::Yes(_)) => {}
2771 Ok(Recovered::No) => unreachable!(),
2772 Err(mut err) => {
2773 enum WrongKw {
2775 Duplicated(Span),
2776 Misplaced(Span),
2777 MisplacedDisallowedQualifier,
2782 }
2783
2784 let mut recover_constness = constness;
2786 let mut recover_coroutine_kind = coroutine_kind;
2787 let mut recover_safety = safety;
2788 let wrong_kw = if self.check_keyword(exp!(Const)) {
2791 match constness {
2792 Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
2793 Const::No => {
2794 recover_constness = Const::Yes(self.token.span);
2795 match parsing_mode {
2796 FrontMatterParsingMode::Function => {
2797 Some(WrongKw::Misplaced(async_start_sp))
2798 }
2799 FrontMatterParsingMode::FunctionPtrType => {
2800 self.dcx().emit_err(FnPointerCannotBeConst {
2801 span: self.token.span,
2802 suggestion: self
2803 .token
2804 .span
2805 .with_lo(self.prev_token.span.hi()),
2806 });
2807 Some(WrongKw::MisplacedDisallowedQualifier)
2808 }
2809 }
2810 }
2811 }
2812 } else if self.check_keyword(exp!(Async)) {
2813 match coroutine_kind {
2814 Some(CoroutineKind::Async { span, .. }) => {
2815 Some(WrongKw::Duplicated(span))
2816 }
2817 Some(CoroutineKind::AsyncGen { span, .. }) => {
2818 Some(WrongKw::Duplicated(span))
2819 }
2820 Some(CoroutineKind::Gen { .. }) => {
2821 recover_coroutine_kind = Some(CoroutineKind::AsyncGen {
2822 span: self.token.span,
2823 closure_id: DUMMY_NODE_ID,
2824 return_impl_trait_id: DUMMY_NODE_ID,
2825 });
2826 Some(WrongKw::Misplaced(unsafe_start_sp))
2828 }
2829 None => {
2830 recover_coroutine_kind = Some(CoroutineKind::Async {
2831 span: self.token.span,
2832 closure_id: DUMMY_NODE_ID,
2833 return_impl_trait_id: DUMMY_NODE_ID,
2834 });
2835 match parsing_mode {
2836 FrontMatterParsingMode::Function => {
2837 Some(WrongKw::Misplaced(async_start_sp))
2838 }
2839 FrontMatterParsingMode::FunctionPtrType => {
2840 self.dcx().emit_err(FnPointerCannotBeAsync {
2841 span: self.token.span,
2842 suggestion: self
2843 .token
2844 .span
2845 .with_lo(self.prev_token.span.hi()),
2846 });
2847 Some(WrongKw::MisplacedDisallowedQualifier)
2848 }
2849 }
2850 }
2851 }
2852 } else if self.check_keyword(exp!(Unsafe)) {
2853 match safety {
2854 Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
2855 Safety::Safe(sp) => {
2856 recover_safety = Safety::Unsafe(self.token.span);
2857 Some(WrongKw::Misplaced(sp))
2858 }
2859 Safety::Default => {
2860 recover_safety = Safety::Unsafe(self.token.span);
2861 Some(WrongKw::Misplaced(ext_start_sp))
2862 }
2863 }
2864 } else if self.check_keyword(exp!(Safe)) {
2865 match safety {
2866 Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
2867 Safety::Unsafe(sp) => {
2868 recover_safety = Safety::Safe(self.token.span);
2869 Some(WrongKw::Misplaced(sp))
2870 }
2871 Safety::Default => {
2872 recover_safety = Safety::Safe(self.token.span);
2873 Some(WrongKw::Misplaced(ext_start_sp))
2874 }
2875 }
2876 } else {
2877 None
2878 };
2879
2880 if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw {
2882 let original_kw = self
2883 .span_to_snippet(original_sp)
2884 .expect("Span extracted directly from keyword should always work");
2885
2886 err.span_suggestion(
2887 self.token_uninterpolated_span(),
2888 format!("`{original_kw}` already used earlier, remove this one"),
2889 "",
2890 Applicability::MachineApplicable,
2891 )
2892 .span_note(original_sp, format!("`{original_kw}` first seen here"));
2893 }
2894 else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
2896 let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
2897 if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
2898 let misplaced_qual_sp = self.token_uninterpolated_span();
2899 let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
2900
2901 err.span_suggestion(
2902 correct_pos_sp.to(misplaced_qual_sp),
2903 format!("`{misplaced_qual}` must come before `{current_qual}`"),
2904 format!("{misplaced_qual} {current_qual}"),
2905 Applicability::MachineApplicable,
2906 ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
2907 }
2908 }
2909 else if self.check_keyword(exp!(Pub)) {
2911 let sp = sp_start.to(self.prev_token.span);
2912 if let Ok(snippet) = self.span_to_snippet(sp) {
2913 let current_vis = match self.parse_visibility(FollowedByType::No) {
2914 Ok(v) => v,
2915 Err(d) => {
2916 d.cancel();
2917 return Err(err);
2918 }
2919 };
2920 let vs = pprust::vis_to_string(¤t_vis);
2921 let vs = vs.trim_end();
2922
2923 if matches!(orig_vis.kind, VisibilityKind::Inherited) {
2925 err.span_suggestion(
2926 sp_start.to(self.prev_token.span),
2927 format!("visibility `{vs}` must come before `{snippet}`"),
2928 format!("{vs} {snippet}"),
2929 Applicability::MachineApplicable,
2930 );
2931 }
2932 else {
2934 err.span_suggestion(
2935 current_vis.span,
2936 "there is already a visibility modifier, remove one",
2937 "",
2938 Applicability::MachineApplicable,
2939 )
2940 .span_note(orig_vis.span, "explicit visibility first seen here");
2941 }
2942 }
2943 }
2944
2945 if let Some(wrong_kw) = wrong_kw
2948 && self.may_recover()
2949 && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
2950 {
2951 self.bump();
2953 self.bump();
2954 if matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) {
2957 err.cancel();
2958 } else {
2959 err.emit();
2960 }
2961 return Ok(FnHeader {
2962 constness: recover_constness,
2963 safety: recover_safety,
2964 coroutine_kind: recover_coroutine_kind,
2965 ext,
2966 });
2967 }
2968
2969 return Err(err);
2970 }
2971 }
2972 }
2973
2974 Ok(FnHeader { constness, safety, coroutine_kind, ext })
2975 }
2976
2977 pub(super) fn parse_fn_decl(
2979 &mut self,
2980 fn_parse_mode: &FnParseMode,
2981 ret_allow_plus: AllowPlus,
2982 recover_return_sign: RecoverReturnSign,
2983 ) -> PResult<'a, Box<FnDecl>> {
2984 Ok(Box::new(FnDecl {
2985 inputs: self.parse_fn_params(fn_parse_mode)?,
2986 output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
2987 }))
2988 }
2989
2990 pub(super) fn parse_fn_params(
2992 &mut self,
2993 fn_parse_mode: &FnParseMode,
2994 ) -> PResult<'a, ThinVec<Param>> {
2995 let mut first_param = true;
2996 if self.token != TokenKind::OpenParen
2998 && !self.token.is_keyword(kw::For)
3000 {
3001 self.dcx()
3003 .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() });
3004 return Ok(ThinVec::new());
3005 }
3006
3007 let (mut params, _) = self.parse_paren_comma_seq(|p| {
3008 p.recover_vcs_conflict_marker();
3009 let snapshot = p.create_snapshot_for_diagnostic();
3010 let param = p.parse_param_general(fn_parse_mode, first_param, true).or_else(|e| {
3011 let guar = e.emit();
3012 let lo = if let TokenKind::OpenParen = p.prev_token.kind {
3016 p.prev_token.span.shrink_to_hi()
3017 } else {
3018 p.prev_token.span
3019 };
3020 p.restore_snapshot(snapshot);
3021 p.eat_to_tokens(&[exp!(Comma), exp!(CloseParen)]);
3023 Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
3025 });
3026 first_param = false;
3028 param
3029 })?;
3030 self.deduplicate_recovered_params_names(&mut params);
3032 Ok(params)
3033 }
3034
3035 pub(super) fn parse_param_general(
3040 &mut self,
3041 fn_parse_mode: &FnParseMode,
3042 first_param: bool,
3043 recover_arg_parse: bool,
3044 ) -> PResult<'a, Param> {
3045 let lo = self.token.span;
3046 let attrs = self.parse_outer_attributes()?;
3047 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
3048 if let Some(mut param) = this.parse_self_param()? {
3050 param.attrs = attrs;
3051 let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
3052 return Ok((res?, Trailing::No, UsePreAttrPos::No));
3053 }
3054
3055 let is_dot_dot_dot = if this.token.kind == token::DotDotDot {
3056 IsDotDotDot::Yes
3057 } else {
3058 IsDotDotDot::No
3059 };
3060 let is_name_required = (fn_parse_mode.req_name)(
3061 this.token.span.with_neighbor(this.prev_token.span).edition(),
3062 is_dot_dot_dot,
3063 );
3064 let is_name_required = if is_name_required && is_dot_dot_dot == IsDotDotDot::Yes {
3065 this.psess.buffer_lint(
3066 VARARGS_WITHOUT_PATTERN,
3067 this.token.span,
3068 ast::CRATE_NODE_ID,
3069 errors::VarargsWithoutPattern { span: this.token.span },
3070 );
3071 false
3072 } else {
3073 is_name_required
3074 };
3075 let (pat, ty) = if is_name_required || this.is_named_param() {
3076 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
3077 let (pat, colon) = this.parse_fn_param_pat_colon()?;
3078 if !colon {
3079 let mut err = this.unexpected().unwrap_err();
3080 return if let Some(ident) = this.parameter_without_type(
3081 &mut err,
3082 pat,
3083 is_name_required,
3084 first_param,
3085 fn_parse_mode,
3086 ) {
3087 let guar = err.emit();
3088 Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No))
3089 } else {
3090 Err(err)
3091 };
3092 }
3093
3094 this.eat_incorrect_doc_comment_for_param_type();
3095 (pat, this.parse_ty_for_param()?)
3096 } else {
3097 debug!("parse_param_general ident_to_pat");
3098 let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
3099 this.eat_incorrect_doc_comment_for_param_type();
3100 let mut ty = this.parse_ty_for_param();
3101
3102 if let Ok(t) = &ty {
3103 if let TyKind::Path(_, Path { segments, .. }) = &t.kind
3105 && let Some(segment) = segments.last()
3106 && let Some(guar) =
3107 this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
3108 {
3109 return Ok((
3110 dummy_arg(segment.ident, guar),
3111 Trailing::No,
3112 UsePreAttrPos::No,
3113 ));
3114 }
3115
3116 if this.token != token::Comma && this.token != token::CloseParen {
3117 ty = this.unexpected_any();
3120 }
3121 }
3122 match ty {
3123 Ok(ty) => {
3124 let pat = this.mk_pat(ty.span, PatKind::Missing);
3125 (Box::new(pat), ty)
3126 }
3127 Err(err) if this.token == token::DotDotDot => return Err(err),
3129 Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
3130 Err(err) if recover_arg_parse => {
3131 err.cancel();
3133 this.restore_snapshot(parser_snapshot_before_ty);
3134 this.recover_arg_parse()?
3135 }
3136 Err(err) => return Err(err),
3137 }
3138 };
3139
3140 let span = lo.to(this.prev_token.span);
3141
3142 Ok((
3143 Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
3144 Trailing::No,
3145 UsePreAttrPos::No,
3146 ))
3147 })
3148 }
3149
3150 fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
3152 let expect_self_ident = |this: &mut Self| match this.token.ident() {
3154 Some((ident, IdentIsRaw::No)) => {
3155 this.bump();
3156 ident
3157 }
3158 _ => unreachable!(),
3159 };
3160 let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
3162 let is_isolated_self = |this: &Self, n| {
3164 this.is_keyword_ahead(n, &[kw::SelfLower])
3165 && this.look_ahead(n + 1, |t| t != &token::PathSep)
3166 };
3167 let is_isolated_pin_const_self = |this: &Self, n| {
3169 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3170 && this.is_keyword_ahead(n + 1, &[kw::Const])
3171 && is_isolated_self(this, n + 2)
3172 };
3173 let is_isolated_mut_self =
3175 |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
3176 let is_isolated_pin_mut_self = |this: &Self, n| {
3178 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3179 && is_isolated_mut_self(this, n + 1)
3180 };
3181 let parse_self_possibly_typed = |this: &mut Self, m| {
3183 let eself_ident = expect_self_ident(this);
3184 let eself_hi = this.prev_token.span;
3185 let eself = if this.eat(exp!(Colon)) {
3186 SelfKind::Explicit(this.parse_ty()?, m)
3187 } else {
3188 SelfKind::Value(m)
3189 };
3190 Ok((eself, eself_ident, eself_hi))
3191 };
3192 let expect_self_ident_not_typed =
3193 |this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
3194 let eself_ident = expect_self_ident(this);
3195
3196 if this.may_recover() && this.eat_noexpect(&token::Colon) {
3198 let snap = this.create_snapshot_for_diagnostic();
3199 match this.parse_ty() {
3200 Ok(ty) => {
3201 this.dcx().emit_err(errors::IncorrectTypeOnSelf {
3202 span: ty.span,
3203 move_self_modifier: errors::MoveSelfModifier {
3204 removal_span: modifier_span,
3205 insertion_span: ty.span.shrink_to_lo(),
3206 modifier: modifier.to_ref_suggestion(),
3207 },
3208 });
3209 }
3210 Err(diag) => {
3211 diag.cancel();
3212 this.restore_snapshot(snap);
3213 }
3214 }
3215 }
3216 eself_ident
3217 };
3218 let recover_self_ptr = |this: &mut Self| {
3220 this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
3221
3222 Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
3223 };
3224
3225 let eself_lo = self.token.span;
3229 let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
3230 token::And => {
3231 let has_lifetime = is_lifetime(self, 1);
3232 let skip_lifetime_count = has_lifetime as usize;
3233 let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3234 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3237 SelfKind::Region(lifetime, Mutability::Not)
3238 } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3239 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3242 self.bump(); SelfKind::Region(lifetime, Mutability::Mut)
3244 } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3245 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3248 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3249 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Not)
3252 } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
3253 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3256 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3257 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Mut)
3260 } else {
3261 return Ok(None);
3263 };
3264 let hi = self.token.span;
3265 let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3266 (eself, self_ident, hi)
3267 }
3268 token::Star if is_isolated_self(self, 1) => {
3270 self.bump();
3271 recover_self_ptr(self)?
3272 }
3273 token::Star
3275 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
3276 {
3277 self.bump();
3278 self.bump();
3279 recover_self_ptr(self)?
3280 }
3281 token::Ident(..) if is_isolated_self(self, 0) => {
3283 parse_self_possibly_typed(self, Mutability::Not)?
3284 }
3285 token::Ident(..) if is_isolated_mut_self(self, 0) => {
3287 self.bump();
3288 parse_self_possibly_typed(self, Mutability::Mut)?
3289 }
3290 _ => return Ok(None),
3291 };
3292
3293 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
3294 Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
3295 }
3296
3297 fn is_named_param(&self) -> bool {
3298 let offset = match &self.token.kind {
3299 token::OpenInvisible(origin) => match origin {
3300 InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
3301 return self.check_noexpect_past_close_delim(&token::Colon);
3302 }
3303 _ => 0,
3304 },
3305 token::And | token::AndAnd => 1,
3306 _ if self.token.is_keyword(kw::Mut) => 1,
3307 _ => 0,
3308 };
3309
3310 self.look_ahead(offset, |t| t.is_ident())
3311 && self.look_ahead(offset + 1, |t| t == &token::Colon)
3312 }
3313
3314 fn recover_self_param(&mut self) -> bool {
3315 matches!(
3316 self.parse_outer_attributes()
3317 .and_then(|_| self.parse_self_param())
3318 .map_err(|e| e.cancel()),
3319 Ok(Some(_))
3320 )
3321 }
3322}
3323
3324enum IsMacroRulesItem {
3325 Yes { has_bang: bool },
3326 No,
3327}
3328
3329#[derive(Copy, Clone, PartialEq, Eq)]
3330pub(super) enum FrontMatterParsingMode {
3331 Function,
3333 FunctionPtrType,
3336}