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(exp!(Extern)) {
232 if self.eat_keyword(exp!(Crate)) {
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 self.is_static_global() {
245 let safety = self.parse_safety(Case::Sensitive);
246 self.bump(); let mutability = self.parse_mutability();
249 self.parse_static_item(safety, mutability)?
250 } else if self.check_keyword(exp!(Trait)) || self.check_trait_front_matter() {
251 self.parse_item_trait(attrs, lo)?
253 } else if self.check_impl_frontmatter() {
254 self.parse_item_impl(attrs, def_())?
256 } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
257 self.recover_const_mut(const_span);
259 self.recover_missing_kw_before_item()?;
260 let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?;
261 ItemKind::Const(Box::new(ConstItem {
262 defaultness: def_(),
263 ident,
264 generics,
265 ty,
266 rhs,
267 define_opaque: None,
268 }))
269 } else if self.is_reuse_path_item() {
270 self.parse_item_delegation()?
271 } else if self.check_keyword(exp!(Mod))
272 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Mod])
273 {
274 self.parse_item_mod(attrs)?
276 } else if self.eat_keyword(exp!(Type)) {
277 self.parse_type_alias(def_())?
279 } else if self.eat_keyword(exp!(Enum)) {
280 self.parse_item_enum()?
282 } else if self.eat_keyword(exp!(Struct)) {
283 self.parse_item_struct()?
285 } else if self.is_kw_followed_by_ident(kw::Union) {
286 self.bump(); self.parse_item_union()?
289 } else if self.is_builtin() {
290 return self.parse_item_builtin();
292 } else if self.eat_keyword(exp!(Macro)) {
293 self.parse_item_decl_macro(lo)?
295 } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() {
296 self.parse_item_macro_rules(vis, has_bang)?
298 } else if self.isnt_macro_invocation()
299 && (self.token.is_ident_named(sym::import)
300 || self.token.is_ident_named(sym::using)
301 || self.token.is_ident_named(sym::include)
302 || self.token.is_ident_named(sym::require))
303 {
304 return self.recover_import_as_use();
305 } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
306 self.recover_missing_kw_before_item()?;
307 return Ok(None);
308 } else if self.isnt_macro_invocation() && case == Case::Sensitive {
309 _ = def_;
310
311 return self.parse_item_kind(
313 attrs,
314 macros_allowed,
315 lo,
316 vis,
317 def,
318 fn_parse_mode,
319 Case::Insensitive,
320 );
321 } else if macros_allowed && self.check_path() {
322 if self.isnt_macro_invocation() {
323 self.recover_missing_kw_before_item()?;
324 }
325 ItemKind::MacCall(Box::new(self.parse_item_macro(vis)?))
327 } else {
328 return Ok(None);
329 };
330 Ok(Some(info))
331 }
332
333 fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
334 let span = self.token.span;
335 let token_name = super::token_descr(&self.token);
336 let snapshot = self.create_snapshot_for_diagnostic();
337 self.bump();
338 match self.parse_use_item() {
339 Ok(u) => {
340 self.dcx().emit_err(errors::RecoverImportAsUse { span, token_name });
341 Ok(Some(u))
342 }
343 Err(e) => {
344 e.cancel();
345 self.restore_snapshot(snapshot);
346 Ok(None)
347 }
348 }
349 }
350
351 fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
352 let tree = self.parse_use_tree()?;
353 if let Err(mut e) = self.expect_semi() {
354 match tree.kind {
355 UseTreeKind::Glob => {
356 e.note("the wildcard token must be last on the path");
357 }
358 UseTreeKind::Nested { .. } => {
359 e.note("glob-like brace syntax must be last on the path");
360 }
361 _ => (),
362 }
363 return Err(e);
364 }
365 Ok(ItemKind::Use(tree))
366 }
367
368 pub(super) fn is_path_start_item(&mut self) -> bool {
370 self.is_kw_followed_by_ident(kw::Union) || self.is_reuse_path_item()
372 || self.check_trait_front_matter() || self.is_async_fn() || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) }
376
377 fn is_reuse_path_item(&mut self) -> bool {
378 self.token.is_keyword(kw::Reuse)
380 && self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep)
381 }
382
383 fn isnt_macro_invocation(&mut self) -> bool {
385 self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep)
386 }
387
388 fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
391 let is_pub = self.prev_token.is_keyword(kw::Pub);
392 let is_const = self.prev_token.is_keyword(kw::Const);
393 let ident_span = self.token.span;
394 let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span };
395 let insert_span = ident_span.shrink_to_lo();
396
397 let ident = if self.token.is_ident()
398 && (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
399 && self.look_ahead(1, |t| {
400 matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen)
401 }) {
402 self.parse_ident().unwrap()
403 } else {
404 return Ok(());
405 };
406
407 let mut found_generics = false;
408 if self.check(exp!(Lt)) {
409 found_generics = true;
410 self.eat_to_tokens(&[exp!(Gt)]);
411 self.bump(); }
413
414 let err = if self.check(exp!(OpenBrace)) {
415 if self.look_ahead(1, |t| *t == token::CloseBrace) {
417 Some(errors::MissingKeywordForItemDefinition::EnumOrStruct { span })
419 } else if self.look_ahead(2, |t| *t == token::Colon)
420 || self.look_ahead(3, |t| *t == token::Colon)
421 {
422 Some(errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident })
424 } else {
425 Some(errors::MissingKeywordForItemDefinition::Enum { span, insert_span, ident })
426 }
427 } else if self.check(exp!(OpenParen)) {
428 self.bump(); let is_method = self.recover_self_param();
431
432 self.consume_block(exp!(OpenParen), exp!(CloseParen), ConsumeClosingDelim::Yes);
433
434 let err = if self.check(exp!(RArrow)) || self.check(exp!(OpenBrace)) {
435 self.eat_to_tokens(&[exp!(OpenBrace)]);
436 self.bump(); self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
438 if is_method {
439 errors::MissingKeywordForItemDefinition::Method { span, insert_span, ident }
440 } else {
441 errors::MissingKeywordForItemDefinition::Function { span, insert_span, ident }
442 }
443 } else if is_pub && self.check(exp!(Semi)) {
444 errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident }
445 } else {
446 errors::MissingKeywordForItemDefinition::Ambiguous {
447 span,
448 subdiag: if found_generics {
449 None
450 } else if let Ok(snippet) = self.span_to_snippet(ident_span) {
451 Some(errors::AmbiguousMissingKwForItemSub::SuggestMacro {
452 span: ident_span,
453 snippet,
454 })
455 } else {
456 Some(errors::AmbiguousMissingKwForItemSub::HelpMacro)
457 },
458 }
459 };
460 Some(err)
461 } else if found_generics {
462 Some(errors::MissingKeywordForItemDefinition::Ambiguous { span, subdiag: None })
463 } else {
464 None
465 };
466
467 if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
468 }
469
470 fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemKind>> {
471 Ok(None)
473 }
474
475 fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
477 let path = self.parse_path(PathStyle::Mod)?; self.expect(exp!(Bang))?; match self.parse_delim_args() {
480 Ok(args) => {
482 self.eat_semi_for_macro_if_needed(&args);
483 self.complain_if_pub_macro(vis, false);
484 Ok(MacCall { path, args })
485 }
486
487 Err(mut err) => {
488 if self.token.is_ident()
490 && let [segment] = path.segments.as_slice()
491 && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some()
492 {
493 err.span_suggestion(
494 path.span,
495 "perhaps you meant to define a macro",
496 "macro_rules",
497 Applicability::MachineApplicable,
498 );
499 }
500 Err(err)
501 }
502 }
503 }
504
505 fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
507 let ([start @ end] | [start, .., end]) = attrs else {
508 return Ok(());
509 };
510 let msg = if end.is_doc_comment() {
511 "expected item after doc comment"
512 } else {
513 "expected item after attributes"
514 };
515 let mut err = self.dcx().struct_span_err(end.span, msg);
516 if end.is_doc_comment() {
517 err.span_label(end.span, "this doc comment doesn't document anything");
518 } else if self.token == TokenKind::Semi {
519 err.span_suggestion_verbose(
520 self.token.span,
521 "consider removing this semicolon",
522 "",
523 Applicability::MaybeIncorrect,
524 );
525 }
526 if let [.., penultimate, _] = attrs {
527 err.span_label(start.span.to(penultimate.span), "other attributes here");
528 }
529 Err(err)
530 }
531
532 fn is_async_fn(&self) -> bool {
533 self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
534 }
535
536 fn parse_polarity(&mut self) -> ast::ImplPolarity {
537 if self.check(exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) {
539 self.bump(); ast::ImplPolarity::Negative(self.prev_token.span)
541 } else {
542 ast::ImplPolarity::Positive
543 }
544 }
545
546 fn parse_item_impl(
561 &mut self,
562 attrs: &mut AttrVec,
563 defaultness: Defaultness,
564 ) -> PResult<'a, ItemKind> {
565 let mut constness = self.parse_constness(Case::Sensitive);
566 let safety = self.parse_safety(Case::Sensitive);
567 self.expect_keyword(exp!(Impl))?;
568
569 let mut generics = if self.choose_generics_over_qpath(0) {
571 self.parse_generics()?
572 } else {
573 let mut generics = Generics::default();
574 generics.span = self.prev_token.span.shrink_to_hi();
577 generics
578 };
579
580 if let Const::No = constness {
581 constness = self.parse_constness(Case::Sensitive);
583 }
584
585 if let Const::Yes(span) = constness {
586 self.psess.gated_spans.gate(sym::const_trait_impl, span);
587 }
588
589 if (self.token_uninterpolated_span().at_least_rust_2018()
591 && self.token.is_keyword(kw::Async))
592 || self.is_kw_followed_by_ident(kw::Async)
593 {
594 self.bump();
595 self.dcx().emit_err(errors::AsyncImpl { span: self.prev_token.span });
596 }
597
598 let polarity = self.parse_polarity();
599
600 let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
602 {
603 let span = self.prev_token.span.between(self.token.span);
604 return Err(self.dcx().create_err(errors::MissingTraitInTraitImpl {
605 span,
606 for_span: span.to(self.token.span),
607 }));
608 } else {
609 self.parse_ty_with_generics_recovery(&generics)?
610 };
611
612 let has_for = self.eat_keyword(exp!(For));
614 let missing_for_span = self.prev_token.span.between(self.token.span);
615
616 let ty_second = if self.token == token::DotDot {
617 self.bump(); Some(self.mk_ty(self.prev_token.span, TyKind::Dummy))
624 } else if has_for || self.token.can_begin_type() {
625 Some(self.parse_ty()?)
626 } else {
627 None
628 };
629
630 generics.where_clause = self.parse_where_clause()?;
631
632 let impl_items = self.parse_item_list(attrs, |p| p.parse_impl_item(ForceCollect::No))?;
633
634 let (of_trait, self_ty) = match ty_second {
635 Some(ty_second) => {
636 if !has_for {
638 self.dcx().emit_err(errors::MissingForInTraitImpl { span: missing_for_span });
639 }
640
641 let ty_first = *ty_first;
642 let path = match ty_first.kind {
643 TyKind::Path(None, path) => path,
645 other => {
646 if let TyKind::ImplTrait(_, bounds) = other
647 && let [bound] = bounds.as_slice()
648 && let GenericBound::Trait(poly_trait_ref) = bound
649 {
650 let extra_impl_kw = ty_first.span.until(bound.span());
654 self.dcx().emit_err(errors::ExtraImplKeywordInTraitImpl {
655 extra_impl_kw,
656 impl_trait_span: ty_first.span,
657 });
658 poly_trait_ref.trait_ref.path.clone()
659 } else {
660 return Err(self.dcx().create_err(
661 errors::ExpectedTraitInTraitImplFoundType { span: ty_first.span },
662 ));
663 }
664 }
665 };
666 let trait_ref = TraitRef { path, ref_id: ty_first.id };
667
668 let of_trait =
669 Some(Box::new(TraitImplHeader { defaultness, safety, polarity, trait_ref }));
670 (of_trait, ty_second)
671 }
672 None => {
673 let self_ty = ty_first;
674 let error = |modifier, modifier_name, modifier_span| {
675 self.dcx().create_err(errors::TraitImplModifierInInherentImpl {
676 span: self_ty.span,
677 modifier,
678 modifier_name,
679 modifier_span,
680 self_ty: self_ty.span,
681 })
682 };
683
684 if let Safety::Unsafe(span) = safety {
685 error("unsafe", "unsafe", span).with_code(E0197).emit();
686 }
687 if let ImplPolarity::Negative(span) = polarity {
688 error("!", "negative", span).emit();
689 }
690 if let Defaultness::Default(def_span) = defaultness {
691 error("default", "default", def_span).emit();
692 }
693 if let Const::Yes(span) = constness {
694 self.psess.gated_spans.gate(sym::const_trait_impl, span);
695 }
696 (None, self_ty)
697 }
698 };
699
700 Ok(ItemKind::Impl(Impl { generics, of_trait, self_ty, items: impl_items, constness }))
701 }
702
703 fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> {
704 let span = self.token.span;
705 self.expect_keyword(exp!(Reuse))?;
706
707 let (qself, path) = if self.eat_lt() {
708 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
709 (Some(qself), path)
710 } else {
711 (None, self.parse_path(PathStyle::Expr)?)
712 };
713
714 let rename = |this: &mut Self| {
715 Ok(if this.eat_keyword(exp!(As)) { Some(this.parse_ident()?) } else { None })
716 };
717 let body = |this: &mut Self| {
718 Ok(if this.check(exp!(OpenBrace)) {
719 Some(this.parse_block()?)
720 } else {
721 this.expect(exp!(Semi))?;
722 None
723 })
724 };
725
726 let item_kind = if self.eat_path_sep() {
727 let suffixes = if self.eat(exp!(Star)) {
728 None
729 } else {
730 let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?));
731 Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0)
732 };
733 let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? };
734 ItemKind::DelegationMac(Box::new(deleg))
735 } else {
736 let rename = rename(self)?;
737 let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
738 let deleg = Delegation {
739 id: DUMMY_NODE_ID,
740 qself,
741 path,
742 ident,
743 rename,
744 body: body(self)?,
745 from_glob: false,
746 };
747 ItemKind::Delegation(Box::new(deleg))
748 };
749
750 let span = span.to(self.prev_token.span);
751 self.psess.gated_spans.gate(sym::fn_delegation, span);
752
753 Ok(item_kind)
754 }
755
756 fn parse_item_list<T>(
757 &mut self,
758 attrs: &mut AttrVec,
759 mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
760 ) -> PResult<'a, ThinVec<T>> {
761 let open_brace_span = self.token.span;
762
763 if self.token == TokenKind::Semi {
765 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
766 self.bump();
767 return Ok(ThinVec::new());
768 }
769
770 self.expect(exp!(OpenBrace))?;
771 attrs.extend(self.parse_inner_attributes()?);
772
773 let mut items = ThinVec::new();
774 while !self.eat(exp!(CloseBrace)) {
775 if self.recover_doc_comment_before_brace() {
776 continue;
777 }
778 self.recover_vcs_conflict_marker();
779 match parse_item(self) {
780 Ok(None) => {
781 let mut is_unnecessary_semicolon = !items.is_empty()
782 && self
800 .span_to_snippet(self.prev_token.span)
801 .is_ok_and(|snippet| snippet == "}")
802 && self.token == token::Semi;
803 let mut semicolon_span = self.token.span;
804 if !is_unnecessary_semicolon {
805 is_unnecessary_semicolon =
807 self.token == token::OpenBrace && self.prev_token == token::Semi;
808 semicolon_span = self.prev_token.span;
809 }
810 let non_item_span = self.token.span;
812 let is_let = self.token.is_keyword(kw::Let);
813
814 let mut err =
815 self.dcx().struct_span_err(non_item_span, "non-item in item list");
816 self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
817 if is_let {
818 err.span_suggestion_verbose(
819 non_item_span,
820 "consider using `const` instead of `let` for associated const",
821 "const",
822 Applicability::MachineApplicable,
823 );
824 } else {
825 err.span_label(open_brace_span, "item list starts here")
826 .span_label(non_item_span, "non-item starts here")
827 .span_label(self.prev_token.span, "item list ends here");
828 }
829 if is_unnecessary_semicolon {
830 err.span_suggestion(
831 semicolon_span,
832 "consider removing this semicolon",
833 "",
834 Applicability::MaybeIncorrect,
835 );
836 }
837 err.emit();
838 break;
839 }
840 Ok(Some(item)) => items.extend(item),
841 Err(err) => {
842 self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
843 err.with_span_label(
844 open_brace_span,
845 "while parsing this item list starting here",
846 )
847 .with_span_label(self.prev_token.span, "the item list ends here")
848 .emit();
849 break;
850 }
851 }
852 }
853 Ok(items)
854 }
855
856 fn recover_doc_comment_before_brace(&mut self) -> bool {
858 if let token::DocComment(..) = self.token.kind {
859 if self.look_ahead(1, |tok| tok == &token::CloseBrace) {
860 struct_span_code_err!(
862 self.dcx(),
863 self.token.span,
864 E0584,
865 "found a documentation comment that doesn't document anything",
866 )
867 .with_span_label(self.token.span, "this doc comment doesn't document anything")
868 .with_help(
869 "doc comments must come before what they document, if a comment was \
870 intended use `//`",
871 )
872 .emit();
873 self.bump();
874 return true;
875 }
876 }
877 false
878 }
879
880 fn parse_defaultness(&mut self) -> Defaultness {
882 if self.check_keyword(exp!(Default))
886 && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
887 {
888 self.bump(); Defaultness::Default(self.prev_token_uninterpolated_span())
890 } else {
891 Defaultness::Final
892 }
893 }
894
895 fn check_trait_front_matter(&mut self) -> bool {
897 self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait])
899 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
901 || 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]))
902 || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Trait, kw::Auto]))
903 }
904
905 fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
907 let constness = self.parse_constness(Case::Sensitive);
908 if let Const::Yes(span) = constness {
909 self.psess.gated_spans.gate(sym::const_trait_impl, span);
910 }
911 let safety = self.parse_safety(Case::Sensitive);
912 let is_auto = if self.eat_keyword(exp!(Auto)) {
914 self.psess.gated_spans.gate(sym::auto_traits, self.prev_token.span);
915 IsAuto::Yes
916 } else {
917 IsAuto::No
918 };
919
920 self.expect_keyword(exp!(Trait))?;
921 let ident = self.parse_ident()?;
922 let mut generics = self.parse_generics()?;
923
924 let had_colon = self.eat(exp!(Colon));
926 let span_at_colon = self.prev_token.span;
927 let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
928
929 let span_before_eq = self.prev_token.span;
930 if self.eat(exp!(Eq)) {
931 if had_colon {
933 let span = span_at_colon.to(span_before_eq);
934 self.dcx().emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
935 }
936
937 let bounds = self.parse_generic_bounds()?;
938 generics.where_clause = self.parse_where_clause()?;
939 self.expect_semi()?;
940
941 let whole_span = lo.to(self.prev_token.span);
942 if is_auto == IsAuto::Yes {
943 self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
944 }
945 if let Safety::Unsafe(_) = safety {
946 self.dcx().emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span });
947 }
948
949 self.psess.gated_spans.gate(sym::trait_alias, whole_span);
950
951 Ok(ItemKind::TraitAlias(Box::new(TraitAlias { constness, ident, generics, bounds })))
952 } else {
953 generics.where_clause = self.parse_where_clause()?;
955 let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
956 Ok(ItemKind::Trait(Box::new(Trait {
957 constness,
958 is_auto,
959 safety,
960 ident,
961 generics,
962 bounds,
963 items,
964 })))
965 }
966 }
967
968 pub fn parse_impl_item(
969 &mut self,
970 force_collect: ForceCollect,
971 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
972 let fn_parse_mode =
973 FnParseMode { req_name: |_, _| true, context: FnContext::Impl, req_body: true };
974 self.parse_assoc_item(fn_parse_mode, force_collect)
975 }
976
977 pub fn parse_trait_item(
978 &mut self,
979 force_collect: ForceCollect,
980 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
981 let fn_parse_mode = FnParseMode {
982 req_name: |edition, _| edition >= Edition::Edition2018,
983 context: FnContext::Trait,
984 req_body: false,
985 };
986 self.parse_assoc_item(fn_parse_mode, force_collect)
987 }
988
989 fn parse_assoc_item(
991 &mut self,
992 fn_parse_mode: FnParseMode,
993 force_collect: ForceCollect,
994 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
995 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
996 |Item { attrs, id, span, vis, kind, tokens }| {
997 let kind = match AssocItemKind::try_from(kind) {
998 Ok(kind) => kind,
999 Err(kind) => match kind {
1000 ItemKind::Static(box StaticItem {
1001 ident,
1002 ty,
1003 safety: _,
1004 mutability: _,
1005 expr,
1006 define_opaque,
1007 }) => {
1008 self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
1009 let rhs = expr.map(ConstItemRhs::Body);
1010 AssocItemKind::Const(Box::new(ConstItem {
1011 defaultness: Defaultness::Final,
1012 ident,
1013 generics: Generics::default(),
1014 ty,
1015 rhs,
1016 define_opaque,
1017 }))
1018 }
1019 _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
1020 },
1021 };
1022 Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1023 },
1024 ))
1025 }
1026
1027 fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
1033 let ident = self.parse_ident()?;
1034 let mut generics = self.parse_generics()?;
1035
1036 let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() };
1038 generics.where_clause = self.parse_where_clause()?;
1039
1040 let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None };
1041
1042 let after_where_clause = self.parse_where_clause()?;
1043
1044 self.expect_semi()?;
1045
1046 Ok(ItemKind::TyAlias(Box::new(TyAlias {
1047 defaultness,
1048 ident,
1049 generics,
1050 after_where_clause,
1051 bounds,
1052 ty,
1053 })))
1054 }
1055
1056 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
1066 let lo = self.token.span;
1067
1068 let mut prefix =
1069 ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo(), tokens: None };
1070 let kind =
1071 if self.check(exp!(OpenBrace)) || self.check(exp!(Star)) || self.is_import_coupler() {
1072 let mod_sep_ctxt = self.token.span.ctxt();
1074 if self.eat_path_sep() {
1075 prefix
1076 .segments
1077 .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
1078 }
1079
1080 self.parse_use_tree_glob_or_nested()?
1081 } else {
1082 prefix = self.parse_path(PathStyle::Mod)?;
1084
1085 if self.eat_path_sep() {
1086 self.parse_use_tree_glob_or_nested()?
1087 } else {
1088 while self.eat_noexpect(&token::Colon) {
1090 self.dcx()
1091 .emit_err(errors::SingleColonImportPath { span: self.prev_token.span });
1092
1093 self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?;
1095 prefix.span = lo.to(self.prev_token.span);
1096 }
1097
1098 UseTreeKind::Simple(self.parse_rename()?)
1099 }
1100 };
1101
1102 Ok(UseTree { prefix, kind, span: lo.to(self.prev_token.span) })
1103 }
1104
1105 fn parse_use_tree_glob_or_nested(&mut self) -> PResult<'a, UseTreeKind> {
1107 Ok(if self.eat(exp!(Star)) {
1108 UseTreeKind::Glob
1109 } else {
1110 let lo = self.token.span;
1111 UseTreeKind::Nested {
1112 items: self.parse_use_tree_list()?,
1113 span: lo.to(self.prev_token.span),
1114 }
1115 })
1116 }
1117
1118 fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> {
1124 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1125 p.recover_vcs_conflict_marker();
1126 Ok((p.parse_use_tree()?, DUMMY_NODE_ID))
1127 })
1128 .map(|(r, _)| r)
1129 }
1130
1131 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
1132 if self.eat_keyword(exp!(As)) {
1133 self.parse_ident_or_underscore().map(Some)
1134 } else {
1135 Ok(None)
1136 }
1137 }
1138
1139 fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
1140 match self.token.ident() {
1141 Some((ident @ Ident { name: kw::Underscore, .. }, IdentIsRaw::No)) => {
1142 self.bump();
1143 Ok(ident)
1144 }
1145 _ => self.parse_ident(),
1146 }
1147 }
1148
1149 fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemKind> {
1158 let orig_ident = self.parse_crate_name_with_dashes()?;
1160 let (orig_name, item_ident) = if let Some(rename) = self.parse_rename()? {
1161 (Some(orig_ident.name), rename)
1162 } else {
1163 (None, orig_ident)
1164 };
1165 self.expect_semi()?;
1166 Ok(ItemKind::ExternCrate(orig_name, item_ident))
1167 }
1168
1169 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
1170 let ident = if self.token.is_keyword(kw::SelfLower) {
1171 self.parse_path_segment_ident()
1172 } else {
1173 self.parse_ident()
1174 }?;
1175
1176 let dash = exp!(Minus);
1177 if self.token != dash.tok {
1178 return Ok(ident);
1179 }
1180
1181 let mut dashes = vec![];
1183 let mut idents = vec![];
1184 while self.eat(dash) {
1185 dashes.push(self.prev_token.span);
1186 idents.push(self.parse_ident()?);
1187 }
1188
1189 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
1190 let mut fixed_name = ident.name.to_string();
1191 for part in idents {
1192 write!(fixed_name, "_{}", part.name).unwrap();
1193 }
1194
1195 self.dcx().emit_err(errors::ExternCrateNameWithDashes {
1196 span: fixed_name_sp,
1197 sugg: errors::ExternCrateNameWithDashesSugg { dashes },
1198 });
1199
1200 Ok(Ident::from_str_and_span(&fixed_name, fixed_name_sp))
1201 }
1202
1203 fn parse_item_foreign_mod(
1214 &mut self,
1215 attrs: &mut AttrVec,
1216 mut safety: Safety,
1217 ) -> PResult<'a, ItemKind> {
1218 let extern_span = self.prev_token_uninterpolated_span();
1219 let abi = self.parse_abi(); if safety == Safety::Default
1222 && self.token.is_keyword(kw::Unsafe)
1223 && self.look_ahead(1, |t| *t == token::OpenBrace)
1224 {
1225 self.expect(exp!(OpenBrace)).unwrap_err().emit();
1226 safety = Safety::Unsafe(self.token.span);
1227 let _ = self.eat_keyword(exp!(Unsafe));
1228 }
1229 Ok(ItemKind::ForeignMod(ast::ForeignMod {
1230 extern_span,
1231 safety,
1232 abi,
1233 items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
1234 }))
1235 }
1236
1237 pub fn parse_foreign_item(
1239 &mut self,
1240 force_collect: ForceCollect,
1241 ) -> PResult<'a, Option<Option<Box<ForeignItem>>>> {
1242 let fn_parse_mode = FnParseMode {
1243 req_name: |_, is_dot_dot_dot| is_dot_dot_dot == IsDotDotDot::No,
1244 context: FnContext::Free,
1245 req_body: false,
1246 };
1247 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
1248 |Item { attrs, id, span, vis, kind, tokens }| {
1249 let kind = match ForeignItemKind::try_from(kind) {
1250 Ok(kind) => kind,
1251 Err(kind) => match kind {
1252 ItemKind::Const(box ConstItem { ident, ty, rhs, .. }) => {
1253 let const_span = Some(span.with_hi(ident.span.lo()))
1254 .filter(|span| span.can_be_used_for_suggestions());
1255 self.dcx().emit_err(errors::ExternItemCannotBeConst {
1256 ident_span: ident.span,
1257 const_span,
1258 });
1259 ForeignItemKind::Static(Box::new(StaticItem {
1260 ident,
1261 ty,
1262 mutability: Mutability::Not,
1263 expr: rhs.map(|b| match b {
1264 ConstItemRhs::TypeConst(anon_const) => anon_const.value,
1265 ConstItemRhs::Body(expr) => expr,
1266 }),
1267 safety: Safety::Default,
1268 define_opaque: None,
1269 }))
1270 }
1271 _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
1272 },
1273 };
1274 Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1275 },
1276 ))
1277 }
1278
1279 fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
1280 let span = self.psess.source_map().guess_head_span(span);
1282 let descr = kind.descr();
1283 let help = match kind {
1284 ItemKind::DelegationMac(deleg) if deleg.suffixes.is_none() => false,
1285 _ => true,
1286 };
1287 self.dcx().emit_err(errors::BadItemKind { span, descr, ctx, help });
1288 None
1289 }
1290
1291 fn is_use_closure(&self) -> bool {
1292 if self.token.is_keyword(kw::Use) {
1293 self.look_ahead(1, |token| {
1295 let dist =
1297 if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 };
1298
1299 self.look_ahead(dist, |token| matches!(token.kind, token::Or | token::OrOr))
1300 })
1301 } else {
1302 false
1303 }
1304 }
1305
1306 fn is_unsafe_foreign_mod(&self) -> bool {
1307 if !self.token.is_keyword(kw::Unsafe) {
1309 return false;
1310 }
1311 if !self.is_keyword_ahead(1, &[kw::Extern]) {
1313 return false;
1314 }
1315
1316 let n = if self.look_ahead(2, |t| t.can_begin_string_literal()) { 3 } else { 2 };
1318
1319 self.tree_look_ahead(n, |t| matches!(t, TokenTree::Delimited(_, _, Delimiter::Brace, _)))
1324 == Some(true)
1325 }
1326
1327 fn is_static_global(&mut self) -> bool {
1328 if self.check_keyword(exp!(Static)) {
1329 !self.look_ahead(1, |token| {
1331 if token.is_keyword(kw::Move) || token.is_keyword(kw::Use) {
1332 return true;
1333 }
1334 matches!(token.kind, token::Or | token::OrOr)
1335 })
1336 } else {
1337 (self.check_keyword(exp!(Unsafe)) || self.check_keyword(exp!(Safe)))
1339 && self.look_ahead(1, |t| t.is_keyword(kw::Static))
1340 }
1341 }
1342
1343 fn recover_const_mut(&mut self, const_span: Span) {
1345 if self.eat_keyword(exp!(Mut)) {
1346 let span = self.prev_token.span;
1347 self.dcx()
1348 .emit_err(errors::ConstGlobalCannotBeMutable { ident_span: span, const_span });
1349 } else if self.eat_keyword(exp!(Let)) {
1350 let span = self.prev_token.span;
1351 self.dcx().emit_err(errors::ConstLetMutuallyExclusive { span: const_span.to(span) });
1352 }
1353 }
1354
1355 fn parse_static_item(
1362 &mut self,
1363 safety: Safety,
1364 mutability: Mutability,
1365 ) -> PResult<'a, ItemKind> {
1366 let ident = self.parse_ident()?;
1367
1368 if self.token == TokenKind::Lt && self.may_recover() {
1369 let generics = self.parse_generics()?;
1370 self.dcx().emit_err(errors::StaticWithGenerics { span: generics.span });
1371 }
1372
1373 let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
1376 (true, false) => self.parse_ty()?,
1377 (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
1380 };
1381
1382 let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1383
1384 self.expect_semi()?;
1385
1386 let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
1387 Ok(ItemKind::Static(Box::new(item)))
1388 }
1389
1390 fn parse_const_item(
1396 &mut self,
1397 attrs: &[Attribute],
1398 ) -> PResult<'a, (Ident, Generics, Box<Ty>, Option<ast::ConstItemRhs>)> {
1399 let ident = self.parse_ident_or_underscore()?;
1400
1401 let mut generics = self.parse_generics()?;
1402
1403 if !generics.span.is_empty() {
1406 self.psess.gated_spans.gate(sym::generic_const_items, generics.span);
1407 }
1408
1409 let ty = match (
1412 self.eat(exp!(Colon)),
1413 self.check(exp!(Eq)) | self.check(exp!(Semi)) | self.check_keyword(exp!(Where)),
1414 ) {
1415 (true, false) => self.parse_ty()?,
1416 (colon, _) => self.recover_missing_global_item_type(colon, None),
1418 };
1419
1420 let before_where_clause =
1423 if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() };
1424
1425 let rhs = if self.eat(exp!(Eq)) {
1426 if attr::contains_name(attrs, sym::type_const) {
1427 Some(ConstItemRhs::TypeConst(self.parse_expr_anon_const()?))
1428 } else {
1429 Some(ConstItemRhs::Body(self.parse_expr()?))
1430 }
1431 } else {
1432 None
1433 };
1434
1435 let after_where_clause = self.parse_where_clause()?;
1436
1437 if before_where_clause.has_where_token
1441 && let Some(rhs) = &rhs
1442 {
1443 self.dcx().emit_err(errors::WhereClauseBeforeConstBody {
1444 span: before_where_clause.span,
1445 name: ident.span,
1446 body: rhs.span(),
1447 sugg: if !after_where_clause.has_where_token {
1448 self.psess.source_map().span_to_snippet(rhs.span()).ok().map(|body_s| {
1449 errors::WhereClauseBeforeConstBodySugg {
1450 left: before_where_clause.span.shrink_to_lo(),
1451 snippet: body_s,
1452 right: before_where_clause.span.shrink_to_hi().to(rhs.span()),
1453 }
1454 })
1455 } else {
1456 None
1459 },
1460 });
1461 }
1462
1463 let mut predicates = before_where_clause.predicates;
1470 predicates.extend(after_where_clause.predicates);
1471 let where_clause = WhereClause {
1472 has_where_token: before_where_clause.has_where_token
1473 || after_where_clause.has_where_token,
1474 predicates,
1475 span: if after_where_clause.has_where_token {
1476 after_where_clause.span
1477 } else {
1478 before_where_clause.span
1479 },
1480 };
1481
1482 if where_clause.has_where_token {
1483 self.psess.gated_spans.gate(sym::generic_const_items, where_clause.span);
1484 }
1485
1486 generics.where_clause = where_clause;
1487
1488 self.expect_semi()?;
1489
1490 Ok((ident, generics, ty, rhs))
1491 }
1492
1493 fn recover_missing_global_item_type(
1496 &mut self,
1497 colon_present: bool,
1498 m: Option<Mutability>,
1499 ) -> Box<Ty> {
1500 let kind = match m {
1503 Some(Mutability::Mut) => "static mut",
1504 Some(Mutability::Not) => "static",
1505 None => "const",
1506 };
1507
1508 let colon = match colon_present {
1509 true => "",
1510 false => ":",
1511 };
1512
1513 let span = self.prev_token.span.shrink_to_hi();
1514 let err = self.dcx().create_err(errors::MissingConstType { span, colon, kind });
1515 err.stash(span, StashKey::ItemNoType);
1516
1517 Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
1520 }
1521
1522 fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
1524 if self.token.is_keyword(kw::Struct) {
1525 let span = self.prev_token.span.to(self.token.span);
1526 let err = errors::EnumStructMutuallyExclusive { span };
1527 if self.look_ahead(1, |t| t.is_ident()) {
1528 self.bump();
1529 self.dcx().emit_err(err);
1530 } else {
1531 return Err(self.dcx().create_err(err));
1532 }
1533 }
1534
1535 let prev_span = self.prev_token.span;
1536 let ident = self.parse_ident()?;
1537 let mut generics = self.parse_generics()?;
1538 generics.where_clause = self.parse_where_clause()?;
1539
1540 let (variants, _) = if self.token == TokenKind::Semi {
1542 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
1543 self.bump();
1544 (thin_vec![], Trailing::No)
1545 } else {
1546 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1547 p.parse_enum_variant(ident.span)
1548 })
1549 .map_err(|mut err| {
1550 err.span_label(ident.span, "while parsing this enum");
1551 if self.prev_token.is_non_reserved_ident() && self.token == token::Colon {
1553 let snapshot = self.create_snapshot_for_diagnostic();
1554 self.bump();
1555 match self.parse_ty() {
1556 Ok(_) => {
1557 err.span_suggestion_verbose(
1558 prev_span,
1559 "perhaps you meant to use `struct` here",
1560 "struct",
1561 Applicability::MaybeIncorrect,
1562 );
1563 }
1564 Err(e) => {
1565 e.cancel();
1566 }
1567 }
1568 self.restore_snapshot(snapshot);
1569 }
1570 self.eat_to_tokens(&[exp!(CloseBrace)]);
1571 self.bump(); err
1573 })?
1574 };
1575
1576 let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
1577 Ok(ItemKind::Enum(ident, generics, enum_definition))
1578 }
1579
1580 fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
1581 self.recover_vcs_conflict_marker();
1582 let variant_attrs = self.parse_outer_attributes()?;
1583 self.recover_vcs_conflict_marker();
1584 let help = "enum variants can be `Variant`, `Variant = <integer>`, \
1585 `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`";
1586 self.collect_tokens(None, variant_attrs, ForceCollect::No, |this, variant_attrs| {
1587 let vlo = this.token.span;
1588
1589 let vis = this.parse_visibility(FollowedByType::No)?;
1590 if !this.recover_nested_adt_item(kw::Enum)? {
1591 return Ok((None, Trailing::No, UsePreAttrPos::No));
1592 }
1593 let ident = this.parse_field_ident("enum", vlo)?;
1594
1595 if this.token == token::Bang {
1596 if let Err(err) = this.unexpected() {
1597 err.with_note(fluent::parse_macro_expands_to_enum_variant).emit();
1598 }
1599
1600 this.bump();
1601 this.parse_delim_args()?;
1602
1603 return Ok((None, Trailing::from(this.token == token::Comma), UsePreAttrPos::No));
1604 }
1605
1606 let struct_def = if this.check(exp!(OpenBrace)) {
1607 let (fields, recovered) =
1609 match this.parse_record_struct_body("struct", ident.span, false) {
1610 Ok((fields, recovered)) => (fields, recovered),
1611 Err(mut err) => {
1612 if this.token == token::Colon {
1613 return Err(err);
1615 }
1616 this.eat_to_tokens(&[exp!(CloseBrace)]);
1617 this.bump(); err.span_label(span, "while parsing this enum");
1619 err.help(help);
1620 let guar = err.emit();
1621 (thin_vec![], Recovered::Yes(guar))
1622 }
1623 };
1624 VariantData::Struct { fields, recovered }
1625 } else if this.check(exp!(OpenParen)) {
1626 let body = match this.parse_tuple_struct_body() {
1627 Ok(body) => body,
1628 Err(mut err) => {
1629 if this.token == token::Colon {
1630 return Err(err);
1632 }
1633 this.eat_to_tokens(&[exp!(CloseParen)]);
1634 this.bump(); err.span_label(span, "while parsing this enum");
1636 err.help(help);
1637 err.emit();
1638 thin_vec![]
1639 }
1640 };
1641 VariantData::Tuple(body, DUMMY_NODE_ID)
1642 } else {
1643 VariantData::Unit(DUMMY_NODE_ID)
1644 };
1645
1646 let disr_expr =
1647 if this.eat(exp!(Eq)) { Some(this.parse_expr_anon_const()?) } else { None };
1648
1649 let vr = ast::Variant {
1650 ident,
1651 vis,
1652 id: DUMMY_NODE_ID,
1653 attrs: variant_attrs,
1654 data: struct_def,
1655 disr_expr,
1656 span: vlo.to(this.prev_token.span),
1657 is_placeholder: false,
1658 };
1659
1660 Ok((Some(vr), Trailing::from(this.token == token::Comma), UsePreAttrPos::No))
1661 })
1662 .map_err(|mut err| {
1663 err.help(help);
1664 err
1665 })
1666 }
1667
1668 fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
1670 let ident = self.parse_ident()?;
1671
1672 let mut generics = self.parse_generics()?;
1673
1674 let vdata = if self.token.is_keyword(kw::Where) {
1689 let tuple_struct_body;
1690 (generics.where_clause, tuple_struct_body) =
1691 self.parse_struct_where_clause(ident, generics.span)?;
1692
1693 if let Some(body) = tuple_struct_body {
1694 let body = VariantData::Tuple(body, DUMMY_NODE_ID);
1696 self.expect_semi()?;
1697 body
1698 } else if self.eat(exp!(Semi)) {
1699 VariantData::Unit(DUMMY_NODE_ID)
1701 } else {
1702 let (fields, recovered) = self.parse_record_struct_body(
1704 "struct",
1705 ident.span,
1706 generics.where_clause.has_where_token,
1707 )?;
1708 VariantData::Struct { fields, recovered }
1709 }
1710 } else if self.eat(exp!(Semi)) {
1712 VariantData::Unit(DUMMY_NODE_ID)
1713 } else if self.token == token::OpenBrace {
1715 let (fields, recovered) = self.parse_record_struct_body(
1716 "struct",
1717 ident.span,
1718 generics.where_clause.has_where_token,
1719 )?;
1720 VariantData::Struct { fields, recovered }
1721 } else if self.token == token::OpenParen {
1723 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1724 generics.where_clause = self.parse_where_clause()?;
1725 self.expect_semi()?;
1726 body
1727 } else {
1728 let err = errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token);
1729 return Err(self.dcx().create_err(err));
1730 };
1731
1732 Ok(ItemKind::Struct(ident, generics, vdata))
1733 }
1734
1735 fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
1737 let ident = self.parse_ident()?;
1738
1739 let mut generics = self.parse_generics()?;
1740
1741 let vdata = if self.token.is_keyword(kw::Where) {
1742 generics.where_clause = self.parse_where_clause()?;
1743 let (fields, recovered) = self.parse_record_struct_body(
1744 "union",
1745 ident.span,
1746 generics.where_clause.has_where_token,
1747 )?;
1748 VariantData::Struct { fields, recovered }
1749 } else if self.token == token::OpenBrace {
1750 let (fields, recovered) = self.parse_record_struct_body(
1751 "union",
1752 ident.span,
1753 generics.where_clause.has_where_token,
1754 )?;
1755 VariantData::Struct { fields, recovered }
1756 } else {
1757 let token_str = super::token_descr(&self.token);
1758 let msg = format!("expected `where` or `{{` after union name, found {token_str}");
1759 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1760 err.span_label(self.token.span, "expected `where` or `{` after union name");
1761 return Err(err);
1762 };
1763
1764 Ok(ItemKind::Union(ident, generics, vdata))
1765 }
1766
1767 pub(crate) fn parse_record_struct_body(
1772 &mut self,
1773 adt_ty: &str,
1774 ident_span: Span,
1775 parsed_where: bool,
1776 ) -> PResult<'a, (ThinVec<FieldDef>, Recovered)> {
1777 let mut fields = ThinVec::new();
1778 let mut recovered = Recovered::No;
1779 if self.eat(exp!(OpenBrace)) {
1780 while self.token != token::CloseBrace {
1781 match self.parse_field_def(adt_ty, ident_span) {
1782 Ok(field) => {
1783 fields.push(field);
1784 }
1785 Err(mut err) => {
1786 self.consume_block(
1787 exp!(OpenBrace),
1788 exp!(CloseBrace),
1789 ConsumeClosingDelim::No,
1790 );
1791 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1792 let guar = err.emit();
1793 recovered = Recovered::Yes(guar);
1794 break;
1795 }
1796 }
1797 }
1798 self.expect(exp!(CloseBrace))?;
1799 } else {
1800 let token_str = super::token_descr(&self.token);
1801 let where_str = if parsed_where { "" } else { "`where`, or " };
1802 let msg = format!("expected {where_str}`{{` after struct name, found {token_str}");
1803 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1804 err.span_label(self.token.span, format!("expected {where_str}`{{` after struct name",));
1805 return Err(err);
1806 }
1807
1808 Ok((fields, recovered))
1809 }
1810
1811 fn parse_unsafe_field(&mut self) -> Safety {
1812 if self.eat_keyword(exp!(Unsafe)) {
1814 let span = self.prev_token.span;
1815 self.psess.gated_spans.gate(sym::unsafe_fields, span);
1816 Safety::Unsafe(span)
1817 } else {
1818 Safety::Default
1819 }
1820 }
1821
1822 pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
1823 self.parse_paren_comma_seq(|p| {
1826 let attrs = p.parse_outer_attributes()?;
1827 p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
1828 let mut snapshot = None;
1829 if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
1830 snapshot = Some(p.create_snapshot_for_diagnostic());
1834 }
1835 let lo = p.token.span;
1836 let vis = match p.parse_visibility(FollowedByType::Yes) {
1837 Ok(vis) => vis,
1838 Err(err) => {
1839 if let Some(ref mut snapshot) = snapshot {
1840 snapshot.recover_vcs_conflict_marker();
1841 }
1842 return Err(err);
1843 }
1844 };
1845 let ty = match p.parse_ty() {
1848 Ok(ty) => ty,
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 mut default = None;
1857 if p.token == token::Eq {
1858 let mut snapshot = p.create_snapshot_for_diagnostic();
1859 snapshot.bump();
1860 match snapshot.parse_expr_anon_const() {
1861 Ok(const_expr) => {
1862 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
1863 p.psess.gated_spans.gate(sym::default_field_values, sp);
1864 p.restore_snapshot(snapshot);
1865 default = Some(const_expr);
1866 }
1867 Err(err) => {
1868 err.cancel();
1869 }
1870 }
1871 }
1872
1873 Ok((
1874 FieldDef {
1875 span: lo.to(ty.span),
1876 vis,
1877 safety: Safety::Default,
1878 ident: None,
1879 id: DUMMY_NODE_ID,
1880 ty,
1881 default,
1882 attrs,
1883 is_placeholder: false,
1884 },
1885 Trailing::from(p.token == token::Comma),
1886 UsePreAttrPos::No,
1887 ))
1888 })
1889 })
1890 .map(|(r, _)| r)
1891 }
1892
1893 fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
1895 self.recover_vcs_conflict_marker();
1896 let attrs = self.parse_outer_attributes()?;
1897 self.recover_vcs_conflict_marker();
1898 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
1899 let lo = this.token.span;
1900 let vis = this.parse_visibility(FollowedByType::No)?;
1901 let safety = this.parse_unsafe_field();
1902 this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
1903 .map(|field| (field, Trailing::No, UsePreAttrPos::No))
1904 })
1905 }
1906
1907 fn parse_single_struct_field(
1909 &mut self,
1910 adt_ty: &str,
1911 lo: Span,
1912 vis: Visibility,
1913 safety: Safety,
1914 attrs: AttrVec,
1915 ident_span: Span,
1916 ) -> PResult<'a, FieldDef> {
1917 let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
1918 match self.token.kind {
1919 token::Comma => {
1920 self.bump();
1921 }
1922 token::Semi => {
1923 self.bump();
1924 let sp = self.prev_token.span;
1925 let mut err =
1926 self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
1927 err.span_suggestion_short(
1928 sp,
1929 "replace `;` with `,`",
1930 ",",
1931 Applicability::MachineApplicable,
1932 );
1933 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1934 err.emit();
1935 }
1936 token::CloseBrace => {}
1937 token::DocComment(..) => {
1938 let previous_span = self.prev_token.span;
1939 let mut err = errors::DocCommentDoesNotDocumentAnything {
1940 span: self.token.span,
1941 missing_comma: None,
1942 };
1943 self.bump(); if self.eat(exp!(Comma)) || self.token == token::CloseBrace {
1945 self.dcx().emit_err(err);
1946 } else {
1947 let sp = previous_span.shrink_to_hi();
1948 err.missing_comma = Some(sp);
1949 return Err(self.dcx().create_err(err));
1950 }
1951 }
1952 _ => {
1953 let sp = self.prev_token.span.shrink_to_hi();
1954 let msg =
1955 format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
1956
1957 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
1959 && let Some(last_segment) = segments.last()
1960 {
1961 let guar = self.check_trailing_angle_brackets(
1962 last_segment,
1963 &[exp!(Comma), exp!(CloseBrace)],
1964 );
1965 if let Some(_guar) = guar {
1966 let _ = self.eat(exp!(Comma));
1969
1970 return Ok(a_var);
1973 }
1974 }
1975
1976 let mut err = self.dcx().struct_span_err(sp, msg);
1977
1978 if self.token.is_ident()
1979 || (self.token == TokenKind::Pound
1980 && (self.look_ahead(1, |t| t == &token::OpenBracket)))
1981 {
1982 err.span_suggestion(
1985 sp,
1986 "try adding a comma",
1987 ",",
1988 Applicability::MachineApplicable,
1989 );
1990 err.emit();
1991 } else {
1992 return Err(err);
1993 }
1994 }
1995 }
1996 Ok(a_var)
1997 }
1998
1999 fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2000 if let Err(err) = self.expect(exp!(Colon)) {
2001 let sm = self.psess.source_map();
2002 let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2003 let semi_typo = self.token == token::Semi
2004 && self.look_ahead(1, |t| {
2005 t.is_path_start()
2006 && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2009 (Ok(l), Ok(r)) => l.line == r.line,
2010 _ => true,
2011 }
2012 });
2013 if eq_typo || semi_typo {
2014 self.bump();
2015 err.with_span_suggestion_short(
2017 self.prev_token.span,
2018 "field names and their types are separated with `:`",
2019 ":",
2020 Applicability::MachineApplicable,
2021 )
2022 .emit();
2023 } else {
2024 return Err(err);
2025 }
2026 }
2027 Ok(())
2028 }
2029
2030 fn parse_name_and_ty(
2032 &mut self,
2033 adt_ty: &str,
2034 lo: Span,
2035 vis: Visibility,
2036 safety: Safety,
2037 attrs: AttrVec,
2038 ) -> PResult<'a, FieldDef> {
2039 let name = self.parse_field_ident(adt_ty, lo)?;
2040 if self.token == token::Bang {
2041 if let Err(mut err) = self.unexpected() {
2042 err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2044 return Err(err);
2045 }
2046 }
2047 self.expect_field_ty_separator()?;
2048 let ty = self.parse_ty()?;
2049 if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2050 self.dcx()
2051 .struct_span_err(self.token.span, "found single colon in a struct field type path")
2052 .with_span_suggestion_verbose(
2053 self.token.span,
2054 "write a path separator here",
2055 "::",
2056 Applicability::MaybeIncorrect,
2057 )
2058 .emit();
2059 }
2060 let default = if self.token == token::Eq {
2061 self.bump();
2062 let const_expr = self.parse_expr_anon_const()?;
2063 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2064 self.psess.gated_spans.gate(sym::default_field_values, sp);
2065 Some(const_expr)
2066 } else {
2067 None
2068 };
2069 Ok(FieldDef {
2070 span: lo.to(self.prev_token.span),
2071 ident: Some(name),
2072 vis,
2073 safety,
2074 id: DUMMY_NODE_ID,
2075 ty,
2076 default,
2077 attrs,
2078 is_placeholder: false,
2079 })
2080 }
2081
2082 fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2085 let (ident, is_raw) = self.ident_or_err(true)?;
2086 if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
2087 let snapshot = self.create_snapshot_for_diagnostic();
2088 let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2089 let inherited_vis =
2090 Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
2091 let fn_parse_mode =
2093 FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
2094 match self.parse_fn(
2095 &mut AttrVec::new(),
2096 fn_parse_mode,
2097 lo,
2098 &inherited_vis,
2099 Case::Insensitive,
2100 ) {
2101 Ok(_) => {
2102 self.dcx().struct_span_err(
2103 lo.to(self.prev_token.span),
2104 format!("functions are not allowed in {adt_ty} definitions"),
2105 )
2106 .with_help(
2107 "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2108 )
2109 .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information")
2110 }
2111 Err(err) => {
2112 err.cancel();
2113 self.restore_snapshot(snapshot);
2114 self.expected_ident_found_err()
2115 }
2116 }
2117 } else if self.eat_keyword(exp!(Struct)) {
2118 match self.parse_item_struct() {
2119 Ok(item) => {
2120 let ItemKind::Struct(ident, ..) = item else { unreachable!() };
2121 self.dcx()
2122 .struct_span_err(
2123 lo.with_hi(ident.span.hi()),
2124 format!("structs are not allowed in {adt_ty} definitions"),
2125 )
2126 .with_help(
2127 "consider creating a new `struct` definition instead of nesting",
2128 )
2129 }
2130 Err(err) => {
2131 err.cancel();
2132 self.restore_snapshot(snapshot);
2133 self.expected_ident_found_err()
2134 }
2135 }
2136 } else {
2137 let mut err = self.expected_ident_found_err();
2138 if self.eat_keyword_noexpect(kw::Let)
2139 && let removal_span = self.prev_token.span.until(self.token.span)
2140 && let Ok(ident) = self
2141 .parse_ident_common(false)
2142 .map_err(|err| err.cancel())
2144 && self.token == TokenKind::Colon
2145 {
2146 err.span_suggestion(
2147 removal_span,
2148 "remove this `let` keyword",
2149 String::new(),
2150 Applicability::MachineApplicable,
2151 );
2152 err.note("the `let` keyword is not allowed in `struct` fields");
2153 err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
2154 err.emit();
2155 return Ok(ident);
2156 } else {
2157 self.restore_snapshot(snapshot);
2158 }
2159 err
2160 };
2161 return Err(err);
2162 }
2163 self.bump();
2164 Ok(ident)
2165 }
2166
2167 fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2175 let ident = self.parse_ident()?;
2176 let body = if self.check(exp!(OpenBrace)) {
2177 self.parse_delim_args()? } else if self.check(exp!(OpenParen)) {
2179 let params = self.parse_token_tree(); let pspan = params.span();
2181 if !self.check(exp!(OpenBrace)) {
2182 self.unexpected()?;
2183 }
2184 let body = self.parse_token_tree(); let bspan = body.span();
2187 let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); let tokens = TokenStream::new(vec![params, arrow, body]);
2189 let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2190 Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2191 } else {
2192 self.unexpected_any()?
2193 };
2194
2195 self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2196 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false }))
2197 }
2198
2199 fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2201 if self.check_keyword(exp!(MacroRules)) {
2202 let macro_rules_span = self.token.span;
2203
2204 if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2205 return IsMacroRulesItem::Yes { has_bang: true };
2206 } else if self.look_ahead(1, |t| t.is_ident()) {
2207 self.dcx().emit_err(errors::MacroRulesMissingBang {
2209 span: macro_rules_span,
2210 hi: macro_rules_span.shrink_to_hi(),
2211 });
2212
2213 return IsMacroRulesItem::Yes { has_bang: false };
2214 }
2215 }
2216
2217 IsMacroRulesItem::No
2218 }
2219
2220 fn parse_item_macro_rules(
2222 &mut self,
2223 vis: &Visibility,
2224 has_bang: bool,
2225 ) -> PResult<'a, ItemKind> {
2226 self.expect_keyword(exp!(MacroRules))?; if has_bang {
2229 self.expect(exp!(Bang))?; }
2231 let ident = self.parse_ident()?;
2232
2233 if self.eat(exp!(Bang)) {
2234 let span = self.prev_token.span;
2236 self.dcx().emit_err(errors::MacroNameRemoveBang { span });
2237 }
2238
2239 let body = self.parse_delim_args()?;
2240 self.eat_semi_for_macro_if_needed(&body);
2241 self.complain_if_pub_macro(vis, true);
2242
2243 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true }))
2244 }
2245
2246 fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
2249 if let VisibilityKind::Inherited = vis.kind {
2250 return;
2251 }
2252
2253 let vstr = pprust::vis_to_string(vis);
2254 let vstr = vstr.trim_end();
2255 if macro_rules {
2256 self.dcx().emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
2257 } else {
2258 self.dcx().emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
2259 }
2260 }
2261
2262 fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) {
2263 if args.need_semicolon() && !self.eat(exp!(Semi)) {
2264 self.report_invalid_macro_expansion_item(args);
2265 }
2266 }
2267
2268 fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) {
2269 let span = args.dspan.entire();
2270 let mut err = self.dcx().struct_span_err(
2271 span,
2272 "macros that expand to items must be delimited with braces or followed by a semicolon",
2273 );
2274 if !span.from_expansion() {
2277 let DelimSpan { open, close } = args.dspan;
2278 err.multipart_suggestion(
2279 "change the delimiters to curly braces",
2280 vec![(open, "{".to_string()), (close, '}'.to_string())],
2281 Applicability::MaybeIncorrect,
2282 );
2283 err.span_suggestion(
2284 span.with_neighbor(self.token.span).shrink_to_hi(),
2285 "add a semicolon",
2286 ';',
2287 Applicability::MaybeIncorrect,
2288 );
2289 }
2290 err.emit();
2291 }
2292
2293 fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
2296 if (self.token.is_keyword(kw::Enum)
2297 || self.token.is_keyword(kw::Struct)
2298 || self.token.is_keyword(kw::Union))
2299 && self.look_ahead(1, |t| t.is_ident())
2300 {
2301 let kw_token = self.token;
2302 let kw_str = pprust::token_to_string(&kw_token);
2303 let item = self.parse_item(ForceCollect::No)?;
2304 let mut item = item.unwrap().span;
2305 if self.token == token::Comma {
2306 item = item.to(self.token.span);
2307 }
2308 self.dcx().emit_err(errors::NestedAdt {
2309 span: kw_token.span,
2310 item,
2311 kw_str,
2312 keyword: keyword.as_str(),
2313 });
2314 return Ok(false);
2316 }
2317 Ok(true)
2318 }
2319}
2320
2321type ReqName = fn(Edition, IsDotDotDot) -> bool;
2330
2331#[derive(Copy, Clone, PartialEq)]
2332pub(crate) enum IsDotDotDot {
2333 Yes,
2334 No,
2335}
2336
2337#[derive(Clone, Copy)]
2345pub(crate) struct FnParseMode {
2346 pub(super) req_name: ReqName,
2372 pub(super) context: FnContext,
2375 pub(super) req_body: bool,
2394}
2395
2396#[derive(Clone, Copy, PartialEq, Eq)]
2399pub(crate) enum FnContext {
2400 Free,
2402 Trait,
2404 Impl,
2406}
2407
2408impl<'a> Parser<'a> {
2410 fn parse_fn(
2412 &mut self,
2413 attrs: &mut AttrVec,
2414 fn_parse_mode: FnParseMode,
2415 sig_lo: Span,
2416 vis: &Visibility,
2417 case: Case,
2418 ) -> PResult<'a, (Ident, FnSig, Generics, Option<Box<FnContract>>, Option<Box<Block>>)> {
2419 let fn_span = self.token.span;
2420 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)
2424 {
2425 Ok(decl) => decl,
2426 Err(old_err) => {
2427 if self.token.is_keyword(kw::For) {
2429 old_err.cancel();
2430 return Err(self.dcx().create_err(errors::FnTypoWithImpl { fn_span }));
2431 } else {
2432 return Err(old_err);
2433 }
2434 }
2435 };
2436
2437 let fn_params_end = self.prev_token.span.shrink_to_hi();
2440
2441 let contract = self.parse_contract()?;
2442
2443 generics.where_clause = self.parse_where_clause()?; let fn_params_end =
2447 if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2448
2449 let mut sig_hi = self.prev_token.span;
2450 let body =
2452 self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
2453 let fn_sig_span = sig_lo.to(sig_hi);
2454 Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
2455 }
2456
2457 fn error_fn_body_not_found(
2459 &mut self,
2460 ident_span: Span,
2461 req_body: bool,
2462 fn_params_end: Option<Span>,
2463 ) -> PResult<'a, ErrorGuaranteed> {
2464 let expected: &[_] =
2465 if req_body { &[exp!(OpenBrace)] } else { &[exp!(Semi), exp!(OpenBrace)] };
2466 match self.expected_one_of_not_found(&[], expected) {
2467 Ok(error_guaranteed) => Ok(error_guaranteed),
2468 Err(mut err) => {
2469 if self.token == token::CloseBrace {
2470 err.span_label(ident_span, "while parsing this `fn`");
2473 Ok(err.emit())
2474 } else if self.token == token::RArrow
2475 && let Some(fn_params_end) = fn_params_end
2476 {
2477 let fn_trait_span =
2483 [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2484 if self.prev_token.is_ident_named(symbol) {
2485 Some(self.prev_token.span)
2486 } else {
2487 None
2488 }
2489 });
2490
2491 let arrow_span = self.token.span;
2496 let ty_span = match self.parse_ret_ty(
2497 AllowPlus::Yes,
2498 RecoverQPath::Yes,
2499 RecoverReturnSign::Yes,
2500 ) {
2501 Ok(ty_span) => ty_span.span().shrink_to_hi(),
2502 Err(parse_error) => {
2503 parse_error.cancel();
2504 return Err(err);
2505 }
2506 };
2507 let ret_ty_span = arrow_span.to(ty_span);
2508
2509 if let Some(fn_trait_span) = fn_trait_span {
2510 err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2513 } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2514 {
2515 err.primary_message(
2519 "return type should be specified after the function parameters",
2520 );
2521 err.subdiagnostic(errors::MisplacedReturnType {
2522 fn_params_end,
2523 snippet,
2524 ret_ty_span,
2525 });
2526 }
2527 Err(err)
2528 } else {
2529 Err(err)
2530 }
2531 }
2532 }
2533 }
2534
2535 fn parse_fn_body(
2539 &mut self,
2540 attrs: &mut AttrVec,
2541 ident: &Ident,
2542 sig_hi: &mut Span,
2543 req_body: bool,
2544 fn_params_end: Option<Span>,
2545 ) -> PResult<'a, Option<Box<Block>>> {
2546 let has_semi = if req_body {
2547 self.token == TokenKind::Semi
2548 } else {
2549 self.check(exp!(Semi))
2551 };
2552 let (inner_attrs, body) = if has_semi {
2553 self.expect_semi()?;
2555 *sig_hi = self.prev_token.span;
2556 (AttrVec::new(), None)
2557 } else if self.check(exp!(OpenBrace)) || self.token.is_metavar_block() {
2558 self.parse_block_common(self.token.span, BlockCheckMode::Default, None)
2559 .map(|(attrs, body)| (attrs, Some(body)))?
2560 } else if self.token == token::Eq {
2561 self.bump(); let eq_sp = self.prev_token.span;
2564 let _ = self.parse_expr()?;
2565 self.expect_semi()?; let span = eq_sp.to(self.prev_token.span);
2567 let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
2568 span,
2569 sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
2570 });
2571 (AttrVec::new(), Some(self.mk_block_err(span, guar)))
2572 } else {
2573 self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
2574 (AttrVec::new(), None)
2575 };
2576 attrs.extend(inner_attrs);
2577 Ok(body)
2578 }
2579
2580 fn check_impl_frontmatter(&mut self) -> bool {
2581 const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe];
2582 if self.check_keyword(exp!(Impl)) {
2585 return true;
2586 }
2587 let mut i = 0;
2588 while i < ALL_QUALS.len() {
2589 let action = self.look_ahead(i, |token| {
2590 if token.is_keyword(kw::Impl) {
2591 return Some(true);
2592 }
2593 if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
2594 return None;
2596 }
2597 Some(false)
2598 });
2599 if let Some(ret) = action {
2600 return ret;
2601 }
2602 i += 1;
2603 }
2604 self.is_keyword_ahead(i, &[kw::Impl])
2605 }
2606
2607 pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
2612 const ALL_QUALS: &[ExpKeywordPair] = &[
2613 exp!(Pub),
2614 exp!(Gen),
2615 exp!(Const),
2616 exp!(Async),
2617 exp!(Unsafe),
2618 exp!(Safe),
2619 exp!(Extern),
2620 ];
2621
2622 let quals: &[_] = if check_pub {
2627 ALL_QUALS
2628 } else {
2629 &[exp!(Gen), exp!(Const), exp!(Async), exp!(Unsafe), exp!(Safe), exp!(Extern)]
2630 };
2631 self.check_keyword_case(exp!(Fn), case) || quals.iter().any(|&exp| self.check_keyword_case(exp, case))
2634 && self.look_ahead(1, |t| {
2635 t.is_keyword_case(kw::Fn, case)
2637 || (
2639 (
2640 t.is_non_raw_ident_where(|i|
2641 quals.iter().any(|exp| exp.kw == i.name)
2642 && i.is_reserved()
2644 )
2645 || case == Case::Insensitive
2646 && t.is_non_raw_ident_where(|i| quals.iter().any(|exp| {
2647 exp.kw.as_str() == i.name.as_str().to_lowercase()
2648 }))
2649 )
2650 && !self.is_unsafe_foreign_mod()
2652 && !self.is_async_gen_block()
2654 && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait])
2656 )
2657 })
2658 || self.check_keyword_case(exp!(Extern), case)
2660 && self.look_ahead(1, |t| t.can_begin_string_literal())
2664 && (self.tree_look_ahead(2, |tt| {
2665 match tt {
2666 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2667 TokenTree::Delimited(..) => false,
2668 }
2669 }) == Some(true) ||
2670 (self.may_recover()
2673 && self.tree_look_ahead(2, |tt| {
2674 match tt {
2675 TokenTree::Token(t, _) =>
2676 ALL_QUALS.iter().any(|exp| {
2677 t.is_keyword(exp.kw)
2678 }),
2679 TokenTree::Delimited(..) => false,
2680 }
2681 }) == Some(true)
2682 && self.tree_look_ahead(3, |tt| {
2683 match tt {
2684 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2685 TokenTree::Delimited(..) => false,
2686 }
2687 }) == Some(true)
2688 )
2689 )
2690 }
2691
2692 pub(super) fn parse_fn_front_matter(
2707 &mut self,
2708 orig_vis: &Visibility,
2709 case: Case,
2710 parsing_mode: FrontMatterParsingMode,
2711 ) -> PResult<'a, FnHeader> {
2712 let sp_start = self.token.span;
2713 let constness = self.parse_constness(case);
2714 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2715 && let Const::Yes(const_span) = constness
2716 {
2717 self.dcx().emit_err(FnPointerCannotBeConst {
2718 span: const_span,
2719 suggestion: const_span.until(self.token.span),
2720 });
2721 }
2722
2723 let async_start_sp = self.token.span;
2724 let coroutine_kind = self.parse_coroutine_kind(case);
2725 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2726 && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind
2727 {
2728 self.dcx().emit_err(FnPointerCannotBeAsync {
2729 span: async_span,
2730 suggestion: async_span.until(self.token.span),
2731 });
2732 }
2733 let unsafe_start_sp = self.token.span;
2736 let safety = self.parse_safety(case);
2737
2738 let ext_start_sp = self.token.span;
2739 let ext = self.parse_extern(case);
2740
2741 if let Some(CoroutineKind::Async { span, .. }) = coroutine_kind {
2742 if span.is_rust_2015() {
2743 self.dcx().emit_err(errors::AsyncFnIn2015 {
2744 span,
2745 help: errors::HelpUseLatestEdition::new(),
2746 });
2747 }
2748 }
2749
2750 match coroutine_kind {
2751 Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
2752 self.psess.gated_spans.gate(sym::gen_blocks, span);
2753 }
2754 Some(CoroutineKind::Async { .. }) | None => {}
2755 }
2756
2757 if !self.eat_keyword_case(exp!(Fn), case) {
2758 match self.expect_one_of(&[], &[]) {
2762 Ok(Recovered::Yes(_)) => {}
2763 Ok(Recovered::No) => unreachable!(),
2764 Err(mut err) => {
2765 enum WrongKw {
2767 Duplicated(Span),
2768 Misplaced(Span),
2769 MisplacedDisallowedQualifier,
2774 }
2775
2776 let mut recover_constness = constness;
2778 let mut recover_coroutine_kind = coroutine_kind;
2779 let mut recover_safety = safety;
2780 let wrong_kw = if self.check_keyword(exp!(Const)) {
2783 match constness {
2784 Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
2785 Const::No => {
2786 recover_constness = Const::Yes(self.token.span);
2787 match parsing_mode {
2788 FrontMatterParsingMode::Function => {
2789 Some(WrongKw::Misplaced(async_start_sp))
2790 }
2791 FrontMatterParsingMode::FunctionPtrType => {
2792 self.dcx().emit_err(FnPointerCannotBeConst {
2793 span: self.token.span,
2794 suggestion: self
2795 .token
2796 .span
2797 .with_lo(self.prev_token.span.hi()),
2798 });
2799 Some(WrongKw::MisplacedDisallowedQualifier)
2800 }
2801 }
2802 }
2803 }
2804 } else if self.check_keyword(exp!(Async)) {
2805 match coroutine_kind {
2806 Some(CoroutineKind::Async { span, .. }) => {
2807 Some(WrongKw::Duplicated(span))
2808 }
2809 Some(CoroutineKind::AsyncGen { span, .. }) => {
2810 Some(WrongKw::Duplicated(span))
2811 }
2812 Some(CoroutineKind::Gen { .. }) => {
2813 recover_coroutine_kind = Some(CoroutineKind::AsyncGen {
2814 span: self.token.span,
2815 closure_id: DUMMY_NODE_ID,
2816 return_impl_trait_id: DUMMY_NODE_ID,
2817 });
2818 Some(WrongKw::Misplaced(unsafe_start_sp))
2820 }
2821 None => {
2822 recover_coroutine_kind = Some(CoroutineKind::Async {
2823 span: self.token.span,
2824 closure_id: DUMMY_NODE_ID,
2825 return_impl_trait_id: DUMMY_NODE_ID,
2826 });
2827 match parsing_mode {
2828 FrontMatterParsingMode::Function => {
2829 Some(WrongKw::Misplaced(async_start_sp))
2830 }
2831 FrontMatterParsingMode::FunctionPtrType => {
2832 self.dcx().emit_err(FnPointerCannotBeAsync {
2833 span: self.token.span,
2834 suggestion: self
2835 .token
2836 .span
2837 .with_lo(self.prev_token.span.hi()),
2838 });
2839 Some(WrongKw::MisplacedDisallowedQualifier)
2840 }
2841 }
2842 }
2843 }
2844 } else if self.check_keyword(exp!(Unsafe)) {
2845 match safety {
2846 Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
2847 Safety::Safe(sp) => {
2848 recover_safety = Safety::Unsafe(self.token.span);
2849 Some(WrongKw::Misplaced(sp))
2850 }
2851 Safety::Default => {
2852 recover_safety = Safety::Unsafe(self.token.span);
2853 Some(WrongKw::Misplaced(ext_start_sp))
2854 }
2855 }
2856 } else if self.check_keyword(exp!(Safe)) {
2857 match safety {
2858 Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
2859 Safety::Unsafe(sp) => {
2860 recover_safety = Safety::Safe(self.token.span);
2861 Some(WrongKw::Misplaced(sp))
2862 }
2863 Safety::Default => {
2864 recover_safety = Safety::Safe(self.token.span);
2865 Some(WrongKw::Misplaced(ext_start_sp))
2866 }
2867 }
2868 } else {
2869 None
2870 };
2871
2872 if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw {
2874 let original_kw = self
2875 .span_to_snippet(original_sp)
2876 .expect("Span extracted directly from keyword should always work");
2877
2878 err.span_suggestion(
2879 self.token_uninterpolated_span(),
2880 format!("`{original_kw}` already used earlier, remove this one"),
2881 "",
2882 Applicability::MachineApplicable,
2883 )
2884 .span_note(original_sp, format!("`{original_kw}` first seen here"));
2885 }
2886 else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
2888 let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
2889 if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
2890 let misplaced_qual_sp = self.token_uninterpolated_span();
2891 let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
2892
2893 err.span_suggestion(
2894 correct_pos_sp.to(misplaced_qual_sp),
2895 format!("`{misplaced_qual}` must come before `{current_qual}`"),
2896 format!("{misplaced_qual} {current_qual}"),
2897 Applicability::MachineApplicable,
2898 ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
2899 }
2900 }
2901 else if self.check_keyword(exp!(Pub)) {
2903 let sp = sp_start.to(self.prev_token.span);
2904 if let Ok(snippet) = self.span_to_snippet(sp) {
2905 let current_vis = match self.parse_visibility(FollowedByType::No) {
2906 Ok(v) => v,
2907 Err(d) => {
2908 d.cancel();
2909 return Err(err);
2910 }
2911 };
2912 let vs = pprust::vis_to_string(¤t_vis);
2913 let vs = vs.trim_end();
2914
2915 if matches!(orig_vis.kind, VisibilityKind::Inherited) {
2917 err.span_suggestion(
2918 sp_start.to(self.prev_token.span),
2919 format!("visibility `{vs}` must come before `{snippet}`"),
2920 format!("{vs} {snippet}"),
2921 Applicability::MachineApplicable,
2922 );
2923 }
2924 else {
2926 err.span_suggestion(
2927 current_vis.span,
2928 "there is already a visibility modifier, remove one",
2929 "",
2930 Applicability::MachineApplicable,
2931 )
2932 .span_note(orig_vis.span, "explicit visibility first seen here");
2933 }
2934 }
2935 }
2936
2937 if let Some(wrong_kw) = wrong_kw
2940 && self.may_recover()
2941 && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
2942 {
2943 self.bump();
2945 self.bump();
2946 if matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) {
2949 err.cancel();
2950 } else {
2951 err.emit();
2952 }
2953 return Ok(FnHeader {
2954 constness: recover_constness,
2955 safety: recover_safety,
2956 coroutine_kind: recover_coroutine_kind,
2957 ext,
2958 });
2959 }
2960
2961 return Err(err);
2962 }
2963 }
2964 }
2965
2966 Ok(FnHeader { constness, safety, coroutine_kind, ext })
2967 }
2968
2969 pub(super) fn parse_fn_decl(
2971 &mut self,
2972 fn_parse_mode: &FnParseMode,
2973 ret_allow_plus: AllowPlus,
2974 recover_return_sign: RecoverReturnSign,
2975 ) -> PResult<'a, Box<FnDecl>> {
2976 Ok(Box::new(FnDecl {
2977 inputs: self.parse_fn_params(fn_parse_mode)?,
2978 output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
2979 }))
2980 }
2981
2982 pub(super) fn parse_fn_params(
2984 &mut self,
2985 fn_parse_mode: &FnParseMode,
2986 ) -> PResult<'a, ThinVec<Param>> {
2987 let mut first_param = true;
2988 if self.token != TokenKind::OpenParen
2990 && !self.token.is_keyword(kw::For)
2992 {
2993 self.dcx()
2995 .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() });
2996 return Ok(ThinVec::new());
2997 }
2998
2999 let (mut params, _) = self.parse_paren_comma_seq(|p| {
3000 p.recover_vcs_conflict_marker();
3001 let snapshot = p.create_snapshot_for_diagnostic();
3002 let param = p.parse_param_general(fn_parse_mode, first_param, true).or_else(|e| {
3003 let guar = e.emit();
3004 let lo = if let TokenKind::OpenParen = p.prev_token.kind {
3008 p.prev_token.span.shrink_to_hi()
3009 } else {
3010 p.prev_token.span
3011 };
3012 p.restore_snapshot(snapshot);
3013 p.eat_to_tokens(&[exp!(Comma), exp!(CloseParen)]);
3015 Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
3017 });
3018 first_param = false;
3020 param
3021 })?;
3022 self.deduplicate_recovered_params_names(&mut params);
3024 Ok(params)
3025 }
3026
3027 pub(super) fn parse_param_general(
3032 &mut self,
3033 fn_parse_mode: &FnParseMode,
3034 first_param: bool,
3035 recover_arg_parse: bool,
3036 ) -> PResult<'a, Param> {
3037 let lo = self.token.span;
3038 let attrs = self.parse_outer_attributes()?;
3039 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
3040 if let Some(mut param) = this.parse_self_param()? {
3042 param.attrs = attrs;
3043 let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
3044 return Ok((res?, Trailing::No, UsePreAttrPos::No));
3045 }
3046
3047 let is_dot_dot_dot = if this.token.kind == token::DotDotDot {
3048 IsDotDotDot::Yes
3049 } else {
3050 IsDotDotDot::No
3051 };
3052 let is_name_required = (fn_parse_mode.req_name)(
3053 this.token.span.with_neighbor(this.prev_token.span).edition(),
3054 is_dot_dot_dot,
3055 );
3056 let is_name_required = if is_name_required && is_dot_dot_dot == IsDotDotDot::Yes {
3057 this.psess.buffer_lint(
3058 VARARGS_WITHOUT_PATTERN,
3059 this.token.span,
3060 ast::CRATE_NODE_ID,
3061 errors::VarargsWithoutPattern { span: this.token.span },
3062 );
3063 false
3064 } else {
3065 is_name_required
3066 };
3067 let (pat, ty) = if is_name_required || this.is_named_param() {
3068 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
3069 let (pat, colon) = this.parse_fn_param_pat_colon()?;
3070 if !colon {
3071 let mut err = this.unexpected().unwrap_err();
3072 return if let Some(ident) = this.parameter_without_type(
3073 &mut err,
3074 pat,
3075 is_name_required,
3076 first_param,
3077 fn_parse_mode,
3078 ) {
3079 let guar = err.emit();
3080 Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No))
3081 } else {
3082 Err(err)
3083 };
3084 }
3085
3086 this.eat_incorrect_doc_comment_for_param_type();
3087 (pat, this.parse_ty_for_param()?)
3088 } else {
3089 debug!("parse_param_general ident_to_pat");
3090 let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
3091 this.eat_incorrect_doc_comment_for_param_type();
3092 let mut ty = this.parse_ty_for_param();
3093
3094 if let Ok(t) = &ty {
3095 if let TyKind::Path(_, Path { segments, .. }) = &t.kind
3097 && let Some(segment) = segments.last()
3098 && let Some(guar) =
3099 this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
3100 {
3101 return Ok((
3102 dummy_arg(segment.ident, guar),
3103 Trailing::No,
3104 UsePreAttrPos::No,
3105 ));
3106 }
3107
3108 if this.token != token::Comma && this.token != token::CloseParen {
3109 ty = this.unexpected_any();
3112 }
3113 }
3114 match ty {
3115 Ok(ty) => {
3116 let pat = this.mk_pat(ty.span, PatKind::Missing);
3117 (Box::new(pat), ty)
3118 }
3119 Err(err) if this.token == token::DotDotDot => return Err(err),
3121 Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
3122 Err(err) if recover_arg_parse => {
3123 err.cancel();
3125 this.restore_snapshot(parser_snapshot_before_ty);
3126 this.recover_arg_parse()?
3127 }
3128 Err(err) => return Err(err),
3129 }
3130 };
3131
3132 let span = lo.to(this.prev_token.span);
3133
3134 Ok((
3135 Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
3136 Trailing::No,
3137 UsePreAttrPos::No,
3138 ))
3139 })
3140 }
3141
3142 fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
3144 let expect_self_ident = |this: &mut Self| match this.token.ident() {
3146 Some((ident, IdentIsRaw::No)) => {
3147 this.bump();
3148 ident
3149 }
3150 _ => unreachable!(),
3151 };
3152 let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
3154 let is_isolated_self = |this: &Self, n| {
3156 this.is_keyword_ahead(n, &[kw::SelfLower])
3157 && this.look_ahead(n + 1, |t| t != &token::PathSep)
3158 };
3159 let is_isolated_pin_const_self = |this: &Self, n| {
3161 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3162 && this.is_keyword_ahead(n + 1, &[kw::Const])
3163 && is_isolated_self(this, n + 2)
3164 };
3165 let is_isolated_mut_self =
3167 |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
3168 let is_isolated_pin_mut_self = |this: &Self, n| {
3170 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3171 && is_isolated_mut_self(this, n + 1)
3172 };
3173 let parse_self_possibly_typed = |this: &mut Self, m| {
3175 let eself_ident = expect_self_ident(this);
3176 let eself_hi = this.prev_token.span;
3177 let eself = if this.eat(exp!(Colon)) {
3178 SelfKind::Explicit(this.parse_ty()?, m)
3179 } else {
3180 SelfKind::Value(m)
3181 };
3182 Ok((eself, eself_ident, eself_hi))
3183 };
3184 let expect_self_ident_not_typed =
3185 |this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
3186 let eself_ident = expect_self_ident(this);
3187
3188 if this.may_recover() && this.eat_noexpect(&token::Colon) {
3190 let snap = this.create_snapshot_for_diagnostic();
3191 match this.parse_ty() {
3192 Ok(ty) => {
3193 this.dcx().emit_err(errors::IncorrectTypeOnSelf {
3194 span: ty.span,
3195 move_self_modifier: errors::MoveSelfModifier {
3196 removal_span: modifier_span,
3197 insertion_span: ty.span.shrink_to_lo(),
3198 modifier: modifier.to_ref_suggestion(),
3199 },
3200 });
3201 }
3202 Err(diag) => {
3203 diag.cancel();
3204 this.restore_snapshot(snap);
3205 }
3206 }
3207 }
3208 eself_ident
3209 };
3210 let recover_self_ptr = |this: &mut Self| {
3212 this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
3213
3214 Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
3215 };
3216
3217 let eself_lo = self.token.span;
3221 let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
3222 token::And => {
3223 let has_lifetime = is_lifetime(self, 1);
3224 let skip_lifetime_count = has_lifetime as usize;
3225 let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3226 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3229 SelfKind::Region(lifetime, Mutability::Not)
3230 } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3231 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3234 self.bump(); SelfKind::Region(lifetime, Mutability::Mut)
3236 } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3237 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3240 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3241 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Not)
3244 } else if is_isolated_pin_mut_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::Mut)
3252 } else {
3253 return Ok(None);
3255 };
3256 let hi = self.token.span;
3257 let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3258 (eself, self_ident, hi)
3259 }
3260 token::Star if is_isolated_self(self, 1) => {
3262 self.bump();
3263 recover_self_ptr(self)?
3264 }
3265 token::Star
3267 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
3268 {
3269 self.bump();
3270 self.bump();
3271 recover_self_ptr(self)?
3272 }
3273 token::Ident(..) if is_isolated_self(self, 0) => {
3275 parse_self_possibly_typed(self, Mutability::Not)?
3276 }
3277 token::Ident(..) if is_isolated_mut_self(self, 0) => {
3279 self.bump();
3280 parse_self_possibly_typed(self, Mutability::Mut)?
3281 }
3282 _ => return Ok(None),
3283 };
3284
3285 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
3286 Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
3287 }
3288
3289 fn is_named_param(&self) -> bool {
3290 let offset = match &self.token.kind {
3291 token::OpenInvisible(origin) => match origin {
3292 InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
3293 return self.check_noexpect_past_close_delim(&token::Colon);
3294 }
3295 _ => 0,
3296 },
3297 token::And | token::AndAnd => 1,
3298 _ if self.token.is_keyword(kw::Mut) => 1,
3299 _ => 0,
3300 };
3301
3302 self.look_ahead(offset, |t| t.is_ident())
3303 && self.look_ahead(offset + 1, |t| t == &token::Colon)
3304 }
3305
3306 fn recover_self_param(&mut self) -> bool {
3307 matches!(
3308 self.parse_outer_attributes()
3309 .and_then(|_| self.parse_self_param())
3310 .map_err(|e| e.cancel()),
3311 Ok(Some(_))
3312 )
3313 }
3314}
3315
3316enum IsMacroRulesItem {
3317 Yes { has_bang: bool },
3318 No,
3319}
3320
3321#[derive(Copy, Clone, PartialEq, Eq)]
3322pub(super) enum FrontMatterParsingMode {
3323 Function,
3325 FunctionPtrType,
3328}