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::{self as ast};
10use rustc_ast_pretty::pprust;
11use rustc_errors::codes::*;
12use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err};
13use rustc_span::edit_distance::edit_distance;
14use rustc_span::edition::Edition;
15use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, source_map, sym};
16use thin_vec::{ThinVec, thin_vec};
17use tracing::debug;
18
19use super::diagnostics::{ConsumeClosingDelim, dummy_arg};
20use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
21use super::{
22 AttrWrapper, ExpKeywordPair, ExpTokenPair, FollowedByType, ForceCollect, Parser, PathStyle,
23 Recovered, Trailing, UsePreAttrPos,
24};
25use crate::errors::{self, FnPointerCannotBeAsync, FnPointerCannotBeConst, MacroExpandsToAdtField};
26use crate::{exp, fluent_generated as fluent};
27
28impl<'a> Parser<'a> {
29 pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> {
31 let (attrs, items, spans) = self.parse_mod(exp!(Eof))?;
32 Ok(ast::Crate { attrs, items, spans, id: DUMMY_NODE_ID, is_placeholder: false })
33 }
34
35 fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemKind> {
37 let safety = self.parse_safety(Case::Sensitive);
38 self.expect_keyword(exp!(Mod))?;
39 let ident = self.parse_ident()?;
40 let mod_kind = if self.eat(exp!(Semi)) {
41 ModKind::Unloaded
42 } else {
43 self.expect(exp!(OpenBrace))?;
44 let (inner_attrs, items, inner_span) = self.parse_mod(exp!(CloseBrace))?;
45 attrs.extend(inner_attrs);
46 ModKind::Loaded(items, Inline::Yes, inner_span, Ok(()))
47 };
48 Ok(ItemKind::Mod(safety, ident, mod_kind))
49 }
50
51 pub fn parse_mod(
56 &mut self,
57 term: ExpTokenPair<'_>,
58 ) -> PResult<'a, (AttrVec, ThinVec<Box<Item>>, ModSpans)> {
59 let lo = self.token.span;
60 let attrs = self.parse_inner_attributes()?;
61
62 let post_attr_lo = self.token.span;
63 let mut items: ThinVec<Box<_>> = ThinVec::new();
64
65 loop {
68 while self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {} let Some(item) = self.parse_item(ForceCollect::No)? else {
70 break;
71 };
72 items.push(item);
73 }
74
75 if !self.eat(term) {
76 let token_str = super::token_descr(&self.token);
77 if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {
78 let is_let = self.token.is_keyword(kw::Let);
79 let is_let_mut = is_let && self.look_ahead(1, |t| t.is_keyword(kw::Mut));
80 let let_has_ident = is_let && !is_let_mut && self.is_kw_followed_by_ident(kw::Let);
81
82 let msg = format!("expected item, found {token_str}");
83 let mut err = self.dcx().struct_span_err(self.token.span, msg);
84
85 let label = if is_let {
86 "`let` cannot be used for global variables"
87 } else {
88 "expected item"
89 };
90 err.span_label(self.token.span, label);
91
92 if is_let {
93 if is_let_mut {
94 err.help("consider using `static` and a `Mutex` instead of `let mut`");
95 } else if let_has_ident {
96 err.span_suggestion_short(
97 self.token.span,
98 "consider using `static` or `const` instead of `let`",
99 "static",
100 Applicability::MaybeIncorrect,
101 );
102 } else {
103 err.help("consider using `static` or `const` instead of `let`");
104 }
105 }
106 err.note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");
107 return Err(err);
108 }
109 }
110
111 let inject_use_span = post_attr_lo.data().with_hi(post_attr_lo.lo());
112 let mod_spans = ModSpans { inner_span: lo.to(self.prev_token.span), inject_use_span };
113 Ok((attrs, items, mod_spans))
114 }
115}
116
117impl<'a> Parser<'a> {
118 pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Box<Item>>> {
119 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
120 self.parse_item_(fn_parse_mode, force_collect).map(|i| i.map(Box::new))
121 }
122
123 fn parse_item_(
124 &mut self,
125 fn_parse_mode: FnParseMode,
126 force_collect: ForceCollect,
127 ) -> PResult<'a, Option<Item>> {
128 self.recover_vcs_conflict_marker();
129 let attrs = self.parse_outer_attributes()?;
130 self.recover_vcs_conflict_marker();
131 self.parse_item_common(attrs, true, false, fn_parse_mode, force_collect)
132 }
133
134 pub(super) fn parse_item_common(
135 &mut self,
136 attrs: AttrWrapper,
137 mac_allowed: bool,
138 attrs_allowed: bool,
139 fn_parse_mode: FnParseMode,
140 force_collect: ForceCollect,
141 ) -> PResult<'a, Option<Item>> {
142 if let Some(item) =
143 self.eat_metavar_seq(MetaVarKind::Item, |this| this.parse_item(ForceCollect::Yes))
144 {
145 let mut item = item.expect("an actual item");
146 attrs.prepend_to_nt_inner(&mut item.attrs);
147 return Ok(Some(*item));
148 }
149
150 self.collect_tokens(None, attrs, force_collect, |this, mut attrs| {
151 let lo = this.token.span;
152 let vis = this.parse_visibility(FollowedByType::No)?;
153 let mut def = this.parse_defaultness();
154 let kind = this.parse_item_kind(
155 &mut attrs,
156 mac_allowed,
157 lo,
158 &vis,
159 &mut def,
160 fn_parse_mode,
161 Case::Sensitive,
162 )?;
163 if let Some(kind) = kind {
164 this.error_on_unconsumed_default(def, &kind);
165 let span = lo.to(this.prev_token.span);
166 let id = DUMMY_NODE_ID;
167 let item = Item { attrs, id, kind, vis, span, tokens: None };
168 return Ok((Some(item), Trailing::No, UsePreAttrPos::No));
169 }
170
171 if !matches!(vis.kind, VisibilityKind::Inherited) {
173 this.dcx().emit_err(errors::VisibilityNotFollowedByItem { span: vis.span, vis });
174 }
175
176 if let Defaultness::Default(span) = def {
177 this.dcx().emit_err(errors::DefaultNotFollowedByItem { span });
178 }
179
180 if !attrs_allowed {
181 this.recover_attrs_no_item(&attrs)?;
182 }
183 Ok((None, Trailing::No, UsePreAttrPos::No))
184 })
185 }
186
187 fn error_on_unconsumed_default(&self, def: Defaultness, kind: &ItemKind) {
189 if let Defaultness::Default(span) = def {
190 self.dcx().emit_err(errors::InappropriateDefault {
191 span,
192 article: kind.article(),
193 descr: kind.descr(),
194 });
195 }
196 }
197
198 fn parse_item_kind(
200 &mut self,
201 attrs: &mut AttrVec,
202 macros_allowed: bool,
203 lo: Span,
204 vis: &Visibility,
205 def: &mut Defaultness,
206 fn_parse_mode: FnParseMode,
207 case: Case,
208 ) -> PResult<'a, Option<ItemKind>> {
209 let check_pub = def == &Defaultness::Final;
210 let mut def_ = || mem::replace(def, Defaultness::Final);
211
212 let info = if !self.is_use_closure() && self.eat_keyword_case(exp!(Use), case) {
213 self.parse_use_item()?
214 } else if self.check_fn_front_matter(check_pub, case) {
215 let (ident, sig, generics, contract, body) =
217 self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
218 ItemKind::Fn(Box::new(Fn {
219 defaultness: def_(),
220 ident,
221 sig,
222 generics,
223 contract,
224 body,
225 define_opaque: None,
226 }))
227 } else if self.eat_keyword(exp!(Extern)) {
228 if self.eat_keyword(exp!(Crate)) {
229 self.parse_item_extern_crate()?
231 } else {
232 self.parse_item_foreign_mod(attrs, Safety::Default)?
234 }
235 } else if self.is_unsafe_foreign_mod() {
236 let safety = self.parse_safety(Case::Sensitive);
238 self.expect_keyword(exp!(Extern))?;
239 self.parse_item_foreign_mod(attrs, safety)?
240 } else if self.is_static_global() {
241 let safety = self.parse_safety(Case::Sensitive);
242 self.bump(); let mutability = self.parse_mutability();
245 self.parse_static_item(safety, mutability)?
246 } else if self.check_keyword(exp!(Trait)) || self.check_trait_front_matter() {
247 self.parse_item_trait(attrs, lo)?
249 } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
250 if self.token.is_keyword(kw::Impl) {
252 self.recover_const_impl(const_span, attrs, def_())?
254 } else {
255 self.recover_const_mut(const_span);
256 self.recover_missing_kw_before_item()?;
257 let (ident, generics, ty, expr) = self.parse_const_item()?;
258 ItemKind::Const(Box::new(ConstItem {
259 defaultness: def_(),
260 ident,
261 generics,
262 ty,
263 expr,
264 define_opaque: None,
265 }))
266 }
267 } else if self.check_keyword(exp!(Impl))
268 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Impl])
269 {
270 self.parse_item_impl(attrs, def_())?
272 } else if self.is_reuse_path_item() {
273 self.parse_item_delegation()?
274 } else if self.check_keyword(exp!(Mod))
275 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Mod])
276 {
277 self.parse_item_mod(attrs)?
279 } else if self.eat_keyword(exp!(Type)) {
280 self.parse_type_alias(def_())?
282 } else if self.eat_keyword(exp!(Enum)) {
283 self.parse_item_enum()?
285 } else if self.eat_keyword(exp!(Struct)) {
286 self.parse_item_struct()?
288 } else if self.is_kw_followed_by_ident(kw::Union) {
289 self.bump(); self.parse_item_union()?
292 } else if self.is_builtin() {
293 return self.parse_item_builtin();
295 } else if self.eat_keyword(exp!(Macro)) {
296 self.parse_item_decl_macro(lo)?
298 } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() {
299 self.parse_item_macro_rules(vis, has_bang)?
301 } else if self.isnt_macro_invocation()
302 && (self.token.is_ident_named(sym::import)
303 || self.token.is_ident_named(sym::using)
304 || self.token.is_ident_named(sym::include)
305 || self.token.is_ident_named(sym::require))
306 {
307 return self.recover_import_as_use();
308 } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
309 self.recover_missing_kw_before_item()?;
310 return Ok(None);
311 } else if self.isnt_macro_invocation() && case == Case::Sensitive {
312 _ = def_;
313
314 return self.parse_item_kind(
316 attrs,
317 macros_allowed,
318 lo,
319 vis,
320 def,
321 fn_parse_mode,
322 Case::Insensitive,
323 );
324 } else if macros_allowed && self.check_path() {
325 if self.isnt_macro_invocation() {
326 self.recover_missing_kw_before_item()?;
327 }
328 ItemKind::MacCall(Box::new(self.parse_item_macro(vis)?))
330 } else {
331 return Ok(None);
332 };
333 Ok(Some(info))
334 }
335
336 fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
337 let span = self.token.span;
338 let token_name = super::token_descr(&self.token);
339 let snapshot = self.create_snapshot_for_diagnostic();
340 self.bump();
341 match self.parse_use_item() {
342 Ok(u) => {
343 self.dcx().emit_err(errors::RecoverImportAsUse { span, token_name });
344 Ok(Some(u))
345 }
346 Err(e) => {
347 e.cancel();
348 self.restore_snapshot(snapshot);
349 Ok(None)
350 }
351 }
352 }
353
354 fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
355 let tree = self.parse_use_tree()?;
356 if let Err(mut e) = self.expect_semi() {
357 match tree.kind {
358 UseTreeKind::Glob => {
359 e.note("the wildcard token must be last on the path");
360 }
361 UseTreeKind::Nested { .. } => {
362 e.note("glob-like brace syntax must be last on the path");
363 }
364 _ => (),
365 }
366 return Err(e);
367 }
368 Ok(ItemKind::Use(tree))
369 }
370
371 pub(super) fn is_path_start_item(&mut self) -> bool {
373 self.is_kw_followed_by_ident(kw::Union) || self.is_reuse_path_item()
375 || self.check_trait_front_matter() || self.is_async_fn() || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) }
379
380 fn is_reuse_path_item(&mut self) -> bool {
381 self.token.is_keyword(kw::Reuse)
383 && self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep)
384 }
385
386 fn isnt_macro_invocation(&mut self) -> bool {
388 self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep)
389 }
390
391 fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
394 let is_pub = self.prev_token.is_keyword(kw::Pub);
395 let is_const = self.prev_token.is_keyword(kw::Const);
396 let ident_span = self.token.span;
397 let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span };
398 let insert_span = ident_span.shrink_to_lo();
399
400 let ident = if self.token.is_ident()
401 && (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
402 && self.look_ahead(1, |t| {
403 matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen)
404 }) {
405 self.parse_ident().unwrap()
406 } else {
407 return Ok(());
408 };
409
410 let mut found_generics = false;
411 if self.check(exp!(Lt)) {
412 found_generics = true;
413 self.eat_to_tokens(&[exp!(Gt)]);
414 self.bump(); }
416
417 let err = if self.check(exp!(OpenBrace)) {
418 if self.look_ahead(1, |t| *t == token::CloseBrace) {
420 Some(errors::MissingKeywordForItemDefinition::EnumOrStruct { span })
422 } else if self.look_ahead(2, |t| *t == token::Colon)
423 || self.look_ahead(3, |t| *t == token::Colon)
424 {
425 Some(errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident })
427 } else {
428 Some(errors::MissingKeywordForItemDefinition::Enum { span, insert_span, ident })
429 }
430 } else if self.check(exp!(OpenParen)) {
431 self.bump(); let is_method = self.recover_self_param();
434
435 self.consume_block(exp!(OpenParen), exp!(CloseParen), ConsumeClosingDelim::Yes);
436
437 let err = if self.check(exp!(RArrow)) || self.check(exp!(OpenBrace)) {
438 self.eat_to_tokens(&[exp!(OpenBrace)]);
439 self.bump(); self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
441 if is_method {
442 errors::MissingKeywordForItemDefinition::Method { span, insert_span, ident }
443 } else {
444 errors::MissingKeywordForItemDefinition::Function { span, insert_span, ident }
445 }
446 } else if is_pub && self.check(exp!(Semi)) {
447 errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident }
448 } else {
449 errors::MissingKeywordForItemDefinition::Ambiguous {
450 span,
451 subdiag: if found_generics {
452 None
453 } else if let Ok(snippet) = self.span_to_snippet(ident_span) {
454 Some(errors::AmbiguousMissingKwForItemSub::SuggestMacro {
455 span: ident_span,
456 snippet,
457 })
458 } else {
459 Some(errors::AmbiguousMissingKwForItemSub::HelpMacro)
460 },
461 }
462 };
463 Some(err)
464 } else if found_generics {
465 Some(errors::MissingKeywordForItemDefinition::Ambiguous { span, subdiag: None })
466 } else {
467 None
468 };
469
470 if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
471 }
472
473 fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemKind>> {
474 Ok(None)
476 }
477
478 fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
480 let path = self.parse_path(PathStyle::Mod)?; self.expect(exp!(Bang))?; match self.parse_delim_args() {
483 Ok(args) => {
485 self.eat_semi_for_macro_if_needed(&args);
486 self.complain_if_pub_macro(vis, false);
487 Ok(MacCall { path, args })
488 }
489
490 Err(mut err) => {
491 if self.token.is_ident()
493 && let [segment] = path.segments.as_slice()
494 && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some()
495 {
496 err.span_suggestion(
497 path.span,
498 "perhaps you meant to define a macro",
499 "macro_rules",
500 Applicability::MachineApplicable,
501 );
502 }
503 Err(err)
504 }
505 }
506 }
507
508 fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
510 let ([start @ end] | [start, .., end]) = attrs else {
511 return Ok(());
512 };
513 let msg = if end.is_doc_comment() {
514 "expected item after doc comment"
515 } else {
516 "expected item after attributes"
517 };
518 let mut err = self.dcx().struct_span_err(end.span, msg);
519 if end.is_doc_comment() {
520 err.span_label(end.span, "this doc comment doesn't document anything");
521 } else if self.token == TokenKind::Semi {
522 err.span_suggestion_verbose(
523 self.token.span,
524 "consider removing this semicolon",
525 "",
526 Applicability::MaybeIncorrect,
527 );
528 }
529 if let [.., penultimate, _] = attrs {
530 err.span_label(start.span.to(penultimate.span), "other attributes here");
531 }
532 Err(err)
533 }
534
535 fn is_async_fn(&self) -> bool {
536 self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
537 }
538
539 fn parse_polarity(&mut self) -> ast::ImplPolarity {
540 if self.check(exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) {
542 self.bump(); ast::ImplPolarity::Negative(self.prev_token.span)
544 } else {
545 ast::ImplPolarity::Positive
546 }
547 }
548
549 fn parse_item_impl(
564 &mut self,
565 attrs: &mut AttrVec,
566 defaultness: Defaultness,
567 ) -> PResult<'a, ItemKind> {
568 let safety = self.parse_safety(Case::Sensitive);
569 self.expect_keyword(exp!(Impl))?;
570
571 let mut generics = if self.choose_generics_over_qpath(0) {
573 self.parse_generics()?
574 } else {
575 let mut generics = Generics::default();
576 generics.span = self.prev_token.span.shrink_to_hi();
579 generics
580 };
581
582 let constness = self.parse_constness(Case::Sensitive);
583 if let Const::Yes(span) = constness {
584 self.psess.gated_spans.gate(sym::const_trait_impl, span);
585 }
586
587 if (self.token_uninterpolated_span().at_least_rust_2018()
589 && self.token.is_keyword(kw::Async))
590 || self.is_kw_followed_by_ident(kw::Async)
591 {
592 self.bump();
593 self.dcx().emit_err(errors::AsyncImpl { span: self.prev_token.span });
594 }
595
596 let polarity = self.parse_polarity();
597
598 let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
600 {
601 let span = self.prev_token.span.between(self.token.span);
602 return Err(self.dcx().create_err(errors::MissingTraitInTraitImpl {
603 span,
604 for_span: span.to(self.token.span),
605 }));
606 } else {
607 self.parse_ty_with_generics_recovery(&generics)?
608 };
609
610 let has_for = self.eat_keyword(exp!(For));
612 let missing_for_span = self.prev_token.span.between(self.token.span);
613
614 let ty_second = if self.token == token::DotDot {
615 self.bump(); Some(self.mk_ty(self.prev_token.span, TyKind::Dummy))
622 } else if has_for || self.token.can_begin_type() {
623 Some(self.parse_ty()?)
624 } else {
625 None
626 };
627
628 generics.where_clause = self.parse_where_clause()?;
629
630 let impl_items = self.parse_item_list(attrs, |p| p.parse_impl_item(ForceCollect::No))?;
631
632 let (of_trait, self_ty) = match ty_second {
633 Some(ty_second) => {
634 if !has_for {
636 self.dcx().emit_err(errors::MissingForInTraitImpl { span: missing_for_span });
637 }
638
639 let ty_first = *ty_first;
640 let path = match ty_first.kind {
641 TyKind::Path(None, path) => path,
643 other => {
644 if let TyKind::ImplTrait(_, bounds) = other
645 && let [bound] = bounds.as_slice()
646 && let GenericBound::Trait(poly_trait_ref) = bound
647 {
648 let extra_impl_kw = ty_first.span.until(bound.span());
652 self.dcx().emit_err(errors::ExtraImplKeywordInTraitImpl {
653 extra_impl_kw,
654 impl_trait_span: ty_first.span,
655 });
656 poly_trait_ref.trait_ref.path.clone()
657 } else {
658 return Err(self.dcx().create_err(
659 errors::ExpectedTraitInTraitImplFoundType { span: ty_first.span },
660 ));
661 }
662 }
663 };
664 let trait_ref = TraitRef { path, ref_id: ty_first.id };
665
666 let of_trait = Some(Box::new(TraitImplHeader {
667 defaultness,
668 safety,
669 constness,
670 polarity,
671 trait_ref,
672 }));
673 (of_trait, ty_second)
674 }
675 None => {
676 let self_ty = ty_first;
677 let error = |modifier, modifier_name, modifier_span| {
678 self.dcx().create_err(errors::TraitImplModifierInInherentImpl {
679 span: self_ty.span,
680 modifier,
681 modifier_name,
682 modifier_span,
683 self_ty: self_ty.span,
684 })
685 };
686
687 if let Safety::Unsafe(span) = safety {
688 error("unsafe", "unsafe", span).with_code(E0197).emit();
689 }
690 if let ImplPolarity::Negative(span) = polarity {
691 error("!", "negative", span).emit();
692 }
693 if let Defaultness::Default(def_span) = defaultness {
694 error("default", "default", def_span).emit();
695 }
696 if let Const::Yes(span) = constness {
697 error("const", "const", span).emit();
698 }
699 (None, self_ty)
700 }
701 };
702
703 Ok(ItemKind::Impl(Impl { generics, of_trait, self_ty, items: impl_items }))
704 }
705
706 fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> {
707 let span = self.token.span;
708 self.expect_keyword(exp!(Reuse))?;
709
710 let (qself, path) = if self.eat_lt() {
711 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
712 (Some(qself), path)
713 } else {
714 (None, self.parse_path(PathStyle::Expr)?)
715 };
716
717 let rename = |this: &mut Self| {
718 Ok(if this.eat_keyword(exp!(As)) { Some(this.parse_ident()?) } else { None })
719 };
720 let body = |this: &mut Self| {
721 Ok(if this.check(exp!(OpenBrace)) {
722 Some(this.parse_block()?)
723 } else {
724 this.expect(exp!(Semi))?;
725 None
726 })
727 };
728
729 let item_kind = if self.eat_path_sep() {
730 let suffixes = if self.eat(exp!(Star)) {
731 None
732 } else {
733 let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?));
734 Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0)
735 };
736 let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? };
737 ItemKind::DelegationMac(Box::new(deleg))
738 } else {
739 let rename = rename(self)?;
740 let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
741 let deleg = Delegation {
742 id: DUMMY_NODE_ID,
743 qself,
744 path,
745 ident,
746 rename,
747 body: body(self)?,
748 from_glob: false,
749 };
750 ItemKind::Delegation(Box::new(deleg))
751 };
752
753 let span = span.to(self.prev_token.span);
754 self.psess.gated_spans.gate(sym::fn_delegation, span);
755
756 Ok(item_kind)
757 }
758
759 fn parse_item_list<T>(
760 &mut self,
761 attrs: &mut AttrVec,
762 mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
763 ) -> PResult<'a, ThinVec<T>> {
764 let open_brace_span = self.token.span;
765
766 if self.token == TokenKind::Semi {
768 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
769 self.bump();
770 return Ok(ThinVec::new());
771 }
772
773 self.expect(exp!(OpenBrace))?;
774 attrs.extend(self.parse_inner_attributes()?);
775
776 let mut items = ThinVec::new();
777 while !self.eat(exp!(CloseBrace)) {
778 if self.recover_doc_comment_before_brace() {
779 continue;
780 }
781 self.recover_vcs_conflict_marker();
782 match parse_item(self) {
783 Ok(None) => {
784 let mut is_unnecessary_semicolon = !items.is_empty()
785 && self
803 .span_to_snippet(self.prev_token.span)
804 .is_ok_and(|snippet| snippet == "}")
805 && self.token == token::Semi;
806 let mut semicolon_span = self.token.span;
807 if !is_unnecessary_semicolon {
808 is_unnecessary_semicolon =
810 self.token == token::OpenBrace && self.prev_token == token::Semi;
811 semicolon_span = self.prev_token.span;
812 }
813 let non_item_span = self.token.span;
815 let is_let = self.token.is_keyword(kw::Let);
816
817 let mut err =
818 self.dcx().struct_span_err(non_item_span, "non-item in item list");
819 self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
820 if is_let {
821 err.span_suggestion_verbose(
822 non_item_span,
823 "consider using `const` instead of `let` for associated const",
824 "const",
825 Applicability::MachineApplicable,
826 );
827 } else {
828 err.span_label(open_brace_span, "item list starts here")
829 .span_label(non_item_span, "non-item starts here")
830 .span_label(self.prev_token.span, "item list ends here");
831 }
832 if is_unnecessary_semicolon {
833 err.span_suggestion(
834 semicolon_span,
835 "consider removing this semicolon",
836 "",
837 Applicability::MaybeIncorrect,
838 );
839 }
840 err.emit();
841 break;
842 }
843 Ok(Some(item)) => items.extend(item),
844 Err(err) => {
845 self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
846 err.with_span_label(
847 open_brace_span,
848 "while parsing this item list starting here",
849 )
850 .with_span_label(self.prev_token.span, "the item list ends here")
851 .emit();
852 break;
853 }
854 }
855 }
856 Ok(items)
857 }
858
859 fn recover_doc_comment_before_brace(&mut self) -> bool {
861 if let token::DocComment(..) = self.token.kind {
862 if self.look_ahead(1, |tok| tok == &token::CloseBrace) {
863 struct_span_code_err!(
865 self.dcx(),
866 self.token.span,
867 E0584,
868 "found a documentation comment that doesn't document anything",
869 )
870 .with_span_label(self.token.span, "this doc comment doesn't document anything")
871 .with_help(
872 "doc comments must come before what they document, if a comment was \
873 intended use `//`",
874 )
875 .emit();
876 self.bump();
877 return true;
878 }
879 }
880 false
881 }
882
883 fn parse_defaultness(&mut self) -> Defaultness {
885 if self.check_keyword(exp!(Default))
889 && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
890 {
891 self.bump(); Defaultness::Default(self.prev_token_uninterpolated_span())
893 } else {
894 Defaultness::Final
895 }
896 }
897
898 fn check_trait_front_matter(&mut self) -> bool {
900 self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait])
902 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
904 || 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]))
905 || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Trait, kw::Auto]))
906 }
907
908 fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
910 let constness = self.parse_constness(Case::Sensitive);
911 if let Const::Yes(span) = constness {
912 self.psess.gated_spans.gate(sym::const_trait_impl, span);
913 }
914 let safety = self.parse_safety(Case::Sensitive);
915 let is_auto = if self.eat_keyword(exp!(Auto)) {
917 self.psess.gated_spans.gate(sym::auto_traits, self.prev_token.span);
918 IsAuto::Yes
919 } else {
920 IsAuto::No
921 };
922
923 self.expect_keyword(exp!(Trait))?;
924 let ident = self.parse_ident()?;
925 let mut generics = self.parse_generics()?;
926
927 let had_colon = self.eat(exp!(Colon));
929 let span_at_colon = self.prev_token.span;
930 let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
931
932 let span_before_eq = self.prev_token.span;
933 if self.eat(exp!(Eq)) {
934 if had_colon {
936 let span = span_at_colon.to(span_before_eq);
937 self.dcx().emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
938 }
939
940 let bounds = self.parse_generic_bounds()?;
941 generics.where_clause = self.parse_where_clause()?;
942 self.expect_semi()?;
943
944 let whole_span = lo.to(self.prev_token.span);
945 if let Const::Yes(_) = constness {
946 self.dcx().emit_err(errors::TraitAliasCannotBeConst { span: whole_span });
947 }
948 if is_auto == IsAuto::Yes {
949 self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
950 }
951 if let Safety::Unsafe(_) = safety {
952 self.dcx().emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span });
953 }
954
955 self.psess.gated_spans.gate(sym::trait_alias, whole_span);
956
957 Ok(ItemKind::TraitAlias(ident, generics, bounds))
958 } else {
959 generics.where_clause = self.parse_where_clause()?;
961 let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
962 Ok(ItemKind::Trait(Box::new(Trait {
963 constness,
964 is_auto,
965 safety,
966 ident,
967 generics,
968 bounds,
969 items,
970 })))
971 }
972 }
973
974 pub fn parse_impl_item(
975 &mut self,
976 force_collect: ForceCollect,
977 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
978 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
979 self.parse_assoc_item(fn_parse_mode, force_collect)
980 }
981
982 pub fn parse_trait_item(
983 &mut self,
984 force_collect: ForceCollect,
985 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
986 let fn_parse_mode =
987 FnParseMode { req_name: |edition| edition >= Edition::Edition2018, req_body: false };
988 self.parse_assoc_item(fn_parse_mode, force_collect)
989 }
990
991 fn parse_assoc_item(
993 &mut self,
994 fn_parse_mode: FnParseMode,
995 force_collect: ForceCollect,
996 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
997 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
998 |Item { attrs, id, span, vis, kind, tokens }| {
999 let kind = match AssocItemKind::try_from(kind) {
1000 Ok(kind) => kind,
1001 Err(kind) => match kind {
1002 ItemKind::Static(box StaticItem {
1003 ident,
1004 ty,
1005 safety: _,
1006 mutability: _,
1007 expr,
1008 define_opaque,
1009 }) => {
1010 self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
1011 AssocItemKind::Const(Box::new(ConstItem {
1012 defaultness: Defaultness::Final,
1013 ident,
1014 generics: Generics::default(),
1015 ty,
1016 expr,
1017 define_opaque,
1018 }))
1019 }
1020 _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
1021 },
1022 };
1023 Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1024 },
1025 ))
1026 }
1027
1028 fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
1034 let ident = self.parse_ident()?;
1035 let mut generics = self.parse_generics()?;
1036
1037 let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() };
1039 let before_where_clause = self.parse_where_clause()?;
1040
1041 let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None };
1042
1043 let after_where_clause = self.parse_where_clause()?;
1044
1045 let where_clauses = TyAliasWhereClauses {
1046 before: TyAliasWhereClause {
1047 has_where_token: before_where_clause.has_where_token,
1048 span: before_where_clause.span,
1049 },
1050 after: TyAliasWhereClause {
1051 has_where_token: after_where_clause.has_where_token,
1052 span: after_where_clause.span,
1053 },
1054 split: before_where_clause.predicates.len(),
1055 };
1056 let mut predicates = before_where_clause.predicates;
1057 predicates.extend(after_where_clause.predicates);
1058 let where_clause = WhereClause {
1059 has_where_token: before_where_clause.has_where_token
1060 || after_where_clause.has_where_token,
1061 predicates,
1062 span: DUMMY_SP,
1063 };
1064 generics.where_clause = where_clause;
1065
1066 self.expect_semi()?;
1067
1068 Ok(ItemKind::TyAlias(Box::new(TyAlias {
1069 defaultness,
1070 ident,
1071 generics,
1072 where_clauses,
1073 bounds,
1074 ty,
1075 })))
1076 }
1077
1078 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
1088 let lo = self.token.span;
1089
1090 let mut prefix =
1091 ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo(), tokens: None };
1092 let kind =
1093 if self.check(exp!(OpenBrace)) || self.check(exp!(Star)) || self.is_import_coupler() {
1094 let mod_sep_ctxt = self.token.span.ctxt();
1096 if self.eat_path_sep() {
1097 prefix
1098 .segments
1099 .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
1100 }
1101
1102 self.parse_use_tree_glob_or_nested()?
1103 } else {
1104 prefix = self.parse_path(PathStyle::Mod)?;
1106
1107 if self.eat_path_sep() {
1108 self.parse_use_tree_glob_or_nested()?
1109 } else {
1110 while self.eat_noexpect(&token::Colon) {
1112 self.dcx()
1113 .emit_err(errors::SingleColonImportPath { span: self.prev_token.span });
1114
1115 self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?;
1117 prefix.span = lo.to(self.prev_token.span);
1118 }
1119
1120 UseTreeKind::Simple(self.parse_rename()?)
1121 }
1122 };
1123
1124 Ok(UseTree { prefix, kind, span: lo.to(self.prev_token.span) })
1125 }
1126
1127 fn parse_use_tree_glob_or_nested(&mut self) -> PResult<'a, UseTreeKind> {
1129 Ok(if self.eat(exp!(Star)) {
1130 UseTreeKind::Glob
1131 } else {
1132 let lo = self.token.span;
1133 UseTreeKind::Nested {
1134 items: self.parse_use_tree_list()?,
1135 span: lo.to(self.prev_token.span),
1136 }
1137 })
1138 }
1139
1140 fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> {
1146 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1147 p.recover_vcs_conflict_marker();
1148 Ok((p.parse_use_tree()?, DUMMY_NODE_ID))
1149 })
1150 .map(|(r, _)| r)
1151 }
1152
1153 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
1154 if self.eat_keyword(exp!(As)) {
1155 self.parse_ident_or_underscore().map(Some)
1156 } else {
1157 Ok(None)
1158 }
1159 }
1160
1161 fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
1162 match self.token.ident() {
1163 Some((ident @ Ident { name: kw::Underscore, .. }, IdentIsRaw::No)) => {
1164 self.bump();
1165 Ok(ident)
1166 }
1167 _ => self.parse_ident(),
1168 }
1169 }
1170
1171 fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemKind> {
1180 let orig_ident = self.parse_crate_name_with_dashes()?;
1182 let (orig_name, item_ident) = if let Some(rename) = self.parse_rename()? {
1183 (Some(orig_ident.name), rename)
1184 } else {
1185 (None, orig_ident)
1186 };
1187 self.expect_semi()?;
1188 Ok(ItemKind::ExternCrate(orig_name, item_ident))
1189 }
1190
1191 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
1192 let ident = if self.token.is_keyword(kw::SelfLower) {
1193 self.parse_path_segment_ident()
1194 } else {
1195 self.parse_ident()
1196 }?;
1197
1198 let dash = exp!(Minus);
1199 if self.token != *dash.tok {
1200 return Ok(ident);
1201 }
1202
1203 let mut dashes = vec![];
1205 let mut idents = vec![];
1206 while self.eat(dash) {
1207 dashes.push(self.prev_token.span);
1208 idents.push(self.parse_ident()?);
1209 }
1210
1211 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
1212 let mut fixed_name = ident.name.to_string();
1213 for part in idents {
1214 write!(fixed_name, "_{}", part.name).unwrap();
1215 }
1216
1217 self.dcx().emit_err(errors::ExternCrateNameWithDashes {
1218 span: fixed_name_sp,
1219 sugg: errors::ExternCrateNameWithDashesSugg { dashes },
1220 });
1221
1222 Ok(Ident::from_str_and_span(&fixed_name, fixed_name_sp))
1223 }
1224
1225 fn parse_item_foreign_mod(
1236 &mut self,
1237 attrs: &mut AttrVec,
1238 mut safety: Safety,
1239 ) -> PResult<'a, ItemKind> {
1240 let extern_span = self.prev_token_uninterpolated_span();
1241 let abi = self.parse_abi(); if safety == Safety::Default
1244 && self.token.is_keyword(kw::Unsafe)
1245 && self.look_ahead(1, |t| *t == token::OpenBrace)
1246 {
1247 self.expect(exp!(OpenBrace)).unwrap_err().emit();
1248 safety = Safety::Unsafe(self.token.span);
1249 let _ = self.eat_keyword(exp!(Unsafe));
1250 }
1251 Ok(ItemKind::ForeignMod(ast::ForeignMod {
1252 extern_span,
1253 safety,
1254 abi,
1255 items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
1256 }))
1257 }
1258
1259 pub fn parse_foreign_item(
1261 &mut self,
1262 force_collect: ForceCollect,
1263 ) -> PResult<'a, Option<Option<Box<ForeignItem>>>> {
1264 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: false };
1265 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
1266 |Item { attrs, id, span, vis, kind, tokens }| {
1267 let kind = match ForeignItemKind::try_from(kind) {
1268 Ok(kind) => kind,
1269 Err(kind) => match kind {
1270 ItemKind::Const(box ConstItem { ident, ty, expr, .. }) => {
1271 let const_span = Some(span.with_hi(ident.span.lo()))
1272 .filter(|span| span.can_be_used_for_suggestions());
1273 self.dcx().emit_err(errors::ExternItemCannotBeConst {
1274 ident_span: ident.span,
1275 const_span,
1276 });
1277 ForeignItemKind::Static(Box::new(StaticItem {
1278 ident,
1279 ty,
1280 mutability: Mutability::Not,
1281 expr,
1282 safety: Safety::Default,
1283 define_opaque: None,
1284 }))
1285 }
1286 _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
1287 },
1288 };
1289 Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1290 },
1291 ))
1292 }
1293
1294 fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
1295 let span = self.psess.source_map().guess_head_span(span);
1297 let descr = kind.descr();
1298 let help = match kind {
1299 ItemKind::DelegationMac(deleg) if deleg.suffixes.is_none() => false,
1300 _ => true,
1301 };
1302 self.dcx().emit_err(errors::BadItemKind { span, descr, ctx, help });
1303 None
1304 }
1305
1306 fn is_use_closure(&self) -> bool {
1307 if self.token.is_keyword(kw::Use) {
1308 self.look_ahead(1, |token| {
1310 let dist =
1312 if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 };
1313
1314 self.look_ahead(dist, |token| matches!(token.kind, token::Or | token::OrOr))
1315 })
1316 } else {
1317 false
1318 }
1319 }
1320
1321 fn is_unsafe_foreign_mod(&self) -> bool {
1322 if !self.token.is_keyword(kw::Unsafe) {
1324 return false;
1325 }
1326 if !self.is_keyword_ahead(1, &[kw::Extern]) {
1328 return false;
1329 }
1330
1331 let n = if self.look_ahead(2, |t| t.can_begin_string_literal()) { 3 } else { 2 };
1333
1334 self.tree_look_ahead(n, |t| matches!(t, TokenTree::Delimited(_, _, Delimiter::Brace, _)))
1339 == Some(true)
1340 }
1341
1342 fn is_static_global(&mut self) -> bool {
1343 if self.check_keyword(exp!(Static)) {
1344 !self.look_ahead(1, |token| {
1346 if token.is_keyword(kw::Move) || token.is_keyword(kw::Use) {
1347 return true;
1348 }
1349 matches!(token.kind, token::Or | token::OrOr)
1350 })
1351 } else {
1352 (self.check_keyword(exp!(Unsafe)) || self.check_keyword(exp!(Safe)))
1354 && self.look_ahead(1, |t| t.is_keyword(kw::Static))
1355 }
1356 }
1357
1358 fn recover_const_mut(&mut self, const_span: Span) {
1360 if self.eat_keyword(exp!(Mut)) {
1361 let span = self.prev_token.span;
1362 self.dcx()
1363 .emit_err(errors::ConstGlobalCannotBeMutable { ident_span: span, const_span });
1364 } else if self.eat_keyword(exp!(Let)) {
1365 let span = self.prev_token.span;
1366 self.dcx().emit_err(errors::ConstLetMutuallyExclusive { span: const_span.to(span) });
1367 }
1368 }
1369
1370 fn recover_const_impl(
1372 &mut self,
1373 const_span: Span,
1374 attrs: &mut AttrVec,
1375 defaultness: Defaultness,
1376 ) -> PResult<'a, ItemKind> {
1377 let impl_span = self.token.span;
1378 let err = self.expected_ident_found_err();
1379
1380 let mut item_kind = match self.parse_item_impl(attrs, defaultness) {
1382 Ok(item_kind) => item_kind,
1383 Err(recovery_error) => {
1384 recovery_error.cancel();
1386 return Err(err);
1387 }
1388 };
1389
1390 match &mut item_kind {
1391 ItemKind::Impl(Impl { of_trait: Some(of_trait), .. }) => {
1392 of_trait.constness = Const::Yes(const_span);
1393
1394 let before_trait = of_trait.trait_ref.path.span.shrink_to_lo();
1395 let const_up_to_impl = const_span.with_hi(impl_span.lo());
1396 err.with_multipart_suggestion(
1397 "you might have meant to write a const trait impl",
1398 vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())],
1399 Applicability::MaybeIncorrect,
1400 )
1401 .emit();
1402 }
1403 ItemKind::Impl { .. } => return Err(err),
1404 _ => unreachable!(),
1405 }
1406
1407 Ok(item_kind)
1408 }
1409
1410 fn parse_static_item(
1417 &mut self,
1418 safety: Safety,
1419 mutability: Mutability,
1420 ) -> PResult<'a, ItemKind> {
1421 let ident = self.parse_ident()?;
1422
1423 if self.token == TokenKind::Lt && self.may_recover() {
1424 let generics = self.parse_generics()?;
1425 self.dcx().emit_err(errors::StaticWithGenerics { span: generics.span });
1426 }
1427
1428 let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
1431 (true, false) => self.parse_ty()?,
1432 (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
1435 };
1436
1437 let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1438
1439 self.expect_semi()?;
1440
1441 let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
1442 Ok(ItemKind::Static(Box::new(item)))
1443 }
1444
1445 fn parse_const_item(
1451 &mut self,
1452 ) -> PResult<'a, (Ident, Generics, Box<Ty>, Option<Box<ast::Expr>>)> {
1453 let ident = self.parse_ident_or_underscore()?;
1454
1455 let mut generics = self.parse_generics()?;
1456
1457 if !generics.span.is_empty() {
1460 self.psess.gated_spans.gate(sym::generic_const_items, generics.span);
1461 }
1462
1463 let ty = match (
1466 self.eat(exp!(Colon)),
1467 self.check(exp!(Eq)) | self.check(exp!(Semi)) | self.check_keyword(exp!(Where)),
1468 ) {
1469 (true, false) => self.parse_ty()?,
1470 (colon, _) => self.recover_missing_global_item_type(colon, None),
1472 };
1473
1474 let before_where_clause =
1477 if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() };
1478
1479 let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1480
1481 let after_where_clause = self.parse_where_clause()?;
1482
1483 if before_where_clause.has_where_token
1487 && let Some(expr) = &expr
1488 {
1489 self.dcx().emit_err(errors::WhereClauseBeforeConstBody {
1490 span: before_where_clause.span,
1491 name: ident.span,
1492 body: expr.span,
1493 sugg: if !after_where_clause.has_where_token {
1494 self.psess.source_map().span_to_snippet(expr.span).ok().map(|body| {
1495 errors::WhereClauseBeforeConstBodySugg {
1496 left: before_where_clause.span.shrink_to_lo(),
1497 snippet: body,
1498 right: before_where_clause.span.shrink_to_hi().to(expr.span),
1499 }
1500 })
1501 } else {
1502 None
1505 },
1506 });
1507 }
1508
1509 let mut predicates = before_where_clause.predicates;
1516 predicates.extend(after_where_clause.predicates);
1517 let where_clause = WhereClause {
1518 has_where_token: before_where_clause.has_where_token
1519 || after_where_clause.has_where_token,
1520 predicates,
1521 span: if after_where_clause.has_where_token {
1522 after_where_clause.span
1523 } else {
1524 before_where_clause.span
1525 },
1526 };
1527
1528 if where_clause.has_where_token {
1529 self.psess.gated_spans.gate(sym::generic_const_items, where_clause.span);
1530 }
1531
1532 generics.where_clause = where_clause;
1533
1534 self.expect_semi()?;
1535
1536 Ok((ident, generics, ty, expr))
1537 }
1538
1539 fn recover_missing_global_item_type(
1542 &mut self,
1543 colon_present: bool,
1544 m: Option<Mutability>,
1545 ) -> Box<Ty> {
1546 let kind = match m {
1549 Some(Mutability::Mut) => "static mut",
1550 Some(Mutability::Not) => "static",
1551 None => "const",
1552 };
1553
1554 let colon = match colon_present {
1555 true => "",
1556 false => ":",
1557 };
1558
1559 let span = self.prev_token.span.shrink_to_hi();
1560 let err = self.dcx().create_err(errors::MissingConstType { span, colon, kind });
1561 err.stash(span, StashKey::ItemNoType);
1562
1563 Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
1566 }
1567
1568 fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
1570 if self.token.is_keyword(kw::Struct) {
1571 let span = self.prev_token.span.to(self.token.span);
1572 let err = errors::EnumStructMutuallyExclusive { span };
1573 if self.look_ahead(1, |t| t.is_ident()) {
1574 self.bump();
1575 self.dcx().emit_err(err);
1576 } else {
1577 return Err(self.dcx().create_err(err));
1578 }
1579 }
1580
1581 let prev_span = self.prev_token.span;
1582 let ident = self.parse_ident()?;
1583 let mut generics = self.parse_generics()?;
1584 generics.where_clause = self.parse_where_clause()?;
1585
1586 let (variants, _) = if self.token == TokenKind::Semi {
1588 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
1589 self.bump();
1590 (thin_vec![], Trailing::No)
1591 } else {
1592 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1593 p.parse_enum_variant(ident.span)
1594 })
1595 .map_err(|mut err| {
1596 err.span_label(ident.span, "while parsing this enum");
1597 if self.prev_token.is_non_reserved_ident() && self.token == token::Colon {
1599 let snapshot = self.create_snapshot_for_diagnostic();
1600 self.bump();
1601 match self.parse_ty() {
1602 Ok(_) => {
1603 err.span_suggestion_verbose(
1604 prev_span,
1605 "perhaps you meant to use `struct` here",
1606 "struct",
1607 Applicability::MaybeIncorrect,
1608 );
1609 }
1610 Err(e) => {
1611 e.cancel();
1612 }
1613 }
1614 self.restore_snapshot(snapshot);
1615 }
1616 self.eat_to_tokens(&[exp!(CloseBrace)]);
1617 self.bump(); err
1619 })?
1620 };
1621
1622 let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
1623 Ok(ItemKind::Enum(ident, generics, enum_definition))
1624 }
1625
1626 fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
1627 self.recover_vcs_conflict_marker();
1628 let variant_attrs = self.parse_outer_attributes()?;
1629 self.recover_vcs_conflict_marker();
1630 let help = "enum variants can be `Variant`, `Variant = <integer>`, \
1631 `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`";
1632 self.collect_tokens(None, variant_attrs, ForceCollect::No, |this, variant_attrs| {
1633 let vlo = this.token.span;
1634
1635 let vis = this.parse_visibility(FollowedByType::No)?;
1636 if !this.recover_nested_adt_item(kw::Enum)? {
1637 return Ok((None, Trailing::No, UsePreAttrPos::No));
1638 }
1639 let ident = this.parse_field_ident("enum", vlo)?;
1640
1641 if this.token == token::Bang {
1642 if let Err(err) = this.unexpected() {
1643 err.with_note(fluent::parse_macro_expands_to_enum_variant).emit();
1644 }
1645
1646 this.bump();
1647 this.parse_delim_args()?;
1648
1649 return Ok((None, Trailing::from(this.token == token::Comma), UsePreAttrPos::No));
1650 }
1651
1652 let struct_def = if this.check(exp!(OpenBrace)) {
1653 let (fields, recovered) =
1655 match this.parse_record_struct_body("struct", ident.span, false) {
1656 Ok((fields, recovered)) => (fields, recovered),
1657 Err(mut err) => {
1658 if this.token == token::Colon {
1659 return Err(err);
1661 }
1662 this.eat_to_tokens(&[exp!(CloseBrace)]);
1663 this.bump(); err.span_label(span, "while parsing this enum");
1665 err.help(help);
1666 let guar = err.emit();
1667 (thin_vec![], Recovered::Yes(guar))
1668 }
1669 };
1670 VariantData::Struct { fields, recovered }
1671 } else if this.check(exp!(OpenParen)) {
1672 let body = match this.parse_tuple_struct_body() {
1673 Ok(body) => body,
1674 Err(mut err) => {
1675 if this.token == token::Colon {
1676 return Err(err);
1678 }
1679 this.eat_to_tokens(&[exp!(CloseParen)]);
1680 this.bump(); err.span_label(span, "while parsing this enum");
1682 err.help(help);
1683 err.emit();
1684 thin_vec![]
1685 }
1686 };
1687 VariantData::Tuple(body, DUMMY_NODE_ID)
1688 } else {
1689 VariantData::Unit(DUMMY_NODE_ID)
1690 };
1691
1692 let disr_expr =
1693 if this.eat(exp!(Eq)) { Some(this.parse_expr_anon_const()?) } else { None };
1694
1695 let vr = ast::Variant {
1696 ident,
1697 vis,
1698 id: DUMMY_NODE_ID,
1699 attrs: variant_attrs,
1700 data: struct_def,
1701 disr_expr,
1702 span: vlo.to(this.prev_token.span),
1703 is_placeholder: false,
1704 };
1705
1706 Ok((Some(vr), Trailing::from(this.token == token::Comma), UsePreAttrPos::No))
1707 })
1708 .map_err(|mut err| {
1709 err.help(help);
1710 err
1711 })
1712 }
1713
1714 fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
1716 let ident = self.parse_ident()?;
1717
1718 let mut generics = self.parse_generics()?;
1719
1720 let vdata = if self.token.is_keyword(kw::Where) {
1735 let tuple_struct_body;
1736 (generics.where_clause, tuple_struct_body) =
1737 self.parse_struct_where_clause(ident, generics.span)?;
1738
1739 if let Some(body) = tuple_struct_body {
1740 let body = VariantData::Tuple(body, DUMMY_NODE_ID);
1742 self.expect_semi()?;
1743 body
1744 } else if self.eat(exp!(Semi)) {
1745 VariantData::Unit(DUMMY_NODE_ID)
1747 } else {
1748 let (fields, recovered) = self.parse_record_struct_body(
1750 "struct",
1751 ident.span,
1752 generics.where_clause.has_where_token,
1753 )?;
1754 VariantData::Struct { fields, recovered }
1755 }
1756 } else if self.eat(exp!(Semi)) {
1758 VariantData::Unit(DUMMY_NODE_ID)
1759 } else if self.token == token::OpenBrace {
1761 let (fields, recovered) = self.parse_record_struct_body(
1762 "struct",
1763 ident.span,
1764 generics.where_clause.has_where_token,
1765 )?;
1766 VariantData::Struct { fields, recovered }
1767 } else if self.token == token::OpenParen {
1769 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1770 generics.where_clause = self.parse_where_clause()?;
1771 self.expect_semi()?;
1772 body
1773 } else {
1774 let err = errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token);
1775 return Err(self.dcx().create_err(err));
1776 };
1777
1778 Ok(ItemKind::Struct(ident, generics, vdata))
1779 }
1780
1781 fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
1783 let ident = self.parse_ident()?;
1784
1785 let mut generics = self.parse_generics()?;
1786
1787 let vdata = if self.token.is_keyword(kw::Where) {
1788 generics.where_clause = self.parse_where_clause()?;
1789 let (fields, recovered) = self.parse_record_struct_body(
1790 "union",
1791 ident.span,
1792 generics.where_clause.has_where_token,
1793 )?;
1794 VariantData::Struct { fields, recovered }
1795 } else if self.token == token::OpenBrace {
1796 let (fields, recovered) = self.parse_record_struct_body(
1797 "union",
1798 ident.span,
1799 generics.where_clause.has_where_token,
1800 )?;
1801 VariantData::Struct { fields, recovered }
1802 } else {
1803 let token_str = super::token_descr(&self.token);
1804 let msg = format!("expected `where` or `{{` after union name, found {token_str}");
1805 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1806 err.span_label(self.token.span, "expected `where` or `{` after union name");
1807 return Err(err);
1808 };
1809
1810 Ok(ItemKind::Union(ident, generics, vdata))
1811 }
1812
1813 pub(crate) fn parse_record_struct_body(
1818 &mut self,
1819 adt_ty: &str,
1820 ident_span: Span,
1821 parsed_where: bool,
1822 ) -> PResult<'a, (ThinVec<FieldDef>, Recovered)> {
1823 let mut fields = ThinVec::new();
1824 let mut recovered = Recovered::No;
1825 if self.eat(exp!(OpenBrace)) {
1826 while self.token != token::CloseBrace {
1827 match self.parse_field_def(adt_ty, ident_span) {
1828 Ok(field) => {
1829 fields.push(field);
1830 }
1831 Err(mut err) => {
1832 self.consume_block(
1833 exp!(OpenBrace),
1834 exp!(CloseBrace),
1835 ConsumeClosingDelim::No,
1836 );
1837 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1838 let guar = err.emit();
1839 recovered = Recovered::Yes(guar);
1840 break;
1841 }
1842 }
1843 }
1844 self.expect(exp!(CloseBrace))?;
1845 } else {
1846 let token_str = super::token_descr(&self.token);
1847 let where_str = if parsed_where { "" } else { "`where`, or " };
1848 let msg = format!("expected {where_str}`{{` after struct name, found {token_str}");
1849 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1850 err.span_label(self.token.span, format!("expected {where_str}`{{` after struct name",));
1851 return Err(err);
1852 }
1853
1854 Ok((fields, recovered))
1855 }
1856
1857 fn parse_unsafe_field(&mut self) -> Safety {
1858 if self.eat_keyword(exp!(Unsafe)) {
1860 let span = self.prev_token.span;
1861 self.psess.gated_spans.gate(sym::unsafe_fields, span);
1862 Safety::Unsafe(span)
1863 } else {
1864 Safety::Default
1865 }
1866 }
1867
1868 pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
1869 self.parse_paren_comma_seq(|p| {
1872 let attrs = p.parse_outer_attributes()?;
1873 p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
1874 let mut snapshot = None;
1875 if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
1876 snapshot = Some(p.create_snapshot_for_diagnostic());
1880 }
1881 let lo = p.token.span;
1882 let vis = match p.parse_visibility(FollowedByType::Yes) {
1883 Ok(vis) => vis,
1884 Err(err) => {
1885 if let Some(ref mut snapshot) = snapshot {
1886 snapshot.recover_vcs_conflict_marker();
1887 }
1888 return Err(err);
1889 }
1890 };
1891 let ty = match p.parse_ty() {
1894 Ok(ty) => ty,
1895 Err(err) => {
1896 if let Some(ref mut snapshot) = snapshot {
1897 snapshot.recover_vcs_conflict_marker();
1898 }
1899 return Err(err);
1900 }
1901 };
1902 let mut default = None;
1903 if p.token == token::Eq {
1904 let mut snapshot = p.create_snapshot_for_diagnostic();
1905 snapshot.bump();
1906 match snapshot.parse_expr_anon_const() {
1907 Ok(const_expr) => {
1908 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
1909 p.psess.gated_spans.gate(sym::default_field_values, sp);
1910 p.restore_snapshot(snapshot);
1911 default = Some(const_expr);
1912 }
1913 Err(err) => {
1914 err.cancel();
1915 }
1916 }
1917 }
1918
1919 Ok((
1920 FieldDef {
1921 span: lo.to(ty.span),
1922 vis,
1923 safety: Safety::Default,
1924 ident: None,
1925 id: DUMMY_NODE_ID,
1926 ty,
1927 default,
1928 attrs,
1929 is_placeholder: false,
1930 },
1931 Trailing::from(p.token == token::Comma),
1932 UsePreAttrPos::No,
1933 ))
1934 })
1935 })
1936 .map(|(r, _)| r)
1937 }
1938
1939 fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
1941 self.recover_vcs_conflict_marker();
1942 let attrs = self.parse_outer_attributes()?;
1943 self.recover_vcs_conflict_marker();
1944 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
1945 let lo = this.token.span;
1946 let vis = this.parse_visibility(FollowedByType::No)?;
1947 let safety = this.parse_unsafe_field();
1948 this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
1949 .map(|field| (field, Trailing::No, UsePreAttrPos::No))
1950 })
1951 }
1952
1953 fn parse_single_struct_field(
1955 &mut self,
1956 adt_ty: &str,
1957 lo: Span,
1958 vis: Visibility,
1959 safety: Safety,
1960 attrs: AttrVec,
1961 ident_span: Span,
1962 ) -> PResult<'a, FieldDef> {
1963 let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
1964 match self.token.kind {
1965 token::Comma => {
1966 self.bump();
1967 }
1968 token::Semi => {
1969 self.bump();
1970 let sp = self.prev_token.span;
1971 let mut err =
1972 self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
1973 err.span_suggestion_short(
1974 sp,
1975 "replace `;` with `,`",
1976 ",",
1977 Applicability::MachineApplicable,
1978 );
1979 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1980 err.emit();
1981 }
1982 token::CloseBrace => {}
1983 token::DocComment(..) => {
1984 let previous_span = self.prev_token.span;
1985 let mut err = errors::DocCommentDoesNotDocumentAnything {
1986 span: self.token.span,
1987 missing_comma: None,
1988 };
1989 self.bump(); if self.eat(exp!(Comma)) || self.token == token::CloseBrace {
1991 self.dcx().emit_err(err);
1992 } else {
1993 let sp = previous_span.shrink_to_hi();
1994 err.missing_comma = Some(sp);
1995 return Err(self.dcx().create_err(err));
1996 }
1997 }
1998 _ => {
1999 let sp = self.prev_token.span.shrink_to_hi();
2000 let msg =
2001 format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
2002
2003 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
2005 && let Some(last_segment) = segments.last()
2006 {
2007 let guar = self.check_trailing_angle_brackets(
2008 last_segment,
2009 &[exp!(Comma), exp!(CloseBrace)],
2010 );
2011 if let Some(_guar) = guar {
2012 let _ = self.eat(exp!(Comma));
2015
2016 return Ok(a_var);
2019 }
2020 }
2021
2022 let mut err = self.dcx().struct_span_err(sp, msg);
2023
2024 if self.token.is_ident()
2025 || (self.token == TokenKind::Pound
2026 && (self.look_ahead(1, |t| t == &token::OpenBracket)))
2027 {
2028 err.span_suggestion(
2031 sp,
2032 "try adding a comma",
2033 ",",
2034 Applicability::MachineApplicable,
2035 );
2036 err.emit();
2037 } else {
2038 return Err(err);
2039 }
2040 }
2041 }
2042 Ok(a_var)
2043 }
2044
2045 fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2046 if let Err(err) = self.expect(exp!(Colon)) {
2047 let sm = self.psess.source_map();
2048 let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2049 let semi_typo = self.token == token::Semi
2050 && self.look_ahead(1, |t| {
2051 t.is_path_start()
2052 && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2055 (Ok(l), Ok(r)) => l.line == r.line,
2056 _ => true,
2057 }
2058 });
2059 if eq_typo || semi_typo {
2060 self.bump();
2061 err.with_span_suggestion_short(
2063 self.prev_token.span,
2064 "field names and their types are separated with `:`",
2065 ":",
2066 Applicability::MachineApplicable,
2067 )
2068 .emit();
2069 } else {
2070 return Err(err);
2071 }
2072 }
2073 Ok(())
2074 }
2075
2076 fn parse_name_and_ty(
2078 &mut self,
2079 adt_ty: &str,
2080 lo: Span,
2081 vis: Visibility,
2082 safety: Safety,
2083 attrs: AttrVec,
2084 ) -> PResult<'a, FieldDef> {
2085 let name = self.parse_field_ident(adt_ty, lo)?;
2086 if self.token == token::Bang {
2087 if let Err(mut err) = self.unexpected() {
2088 err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2090 return Err(err);
2091 }
2092 }
2093 self.expect_field_ty_separator()?;
2094 let ty = self.parse_ty()?;
2095 if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2096 self.dcx()
2097 .struct_span_err(self.token.span, "found single colon in a struct field type path")
2098 .with_span_suggestion_verbose(
2099 self.token.span,
2100 "write a path separator here",
2101 "::",
2102 Applicability::MaybeIncorrect,
2103 )
2104 .emit();
2105 }
2106 let default = if self.token == token::Eq {
2107 self.bump();
2108 let const_expr = self.parse_expr_anon_const()?;
2109 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2110 self.psess.gated_spans.gate(sym::default_field_values, sp);
2111 Some(const_expr)
2112 } else {
2113 None
2114 };
2115 Ok(FieldDef {
2116 span: lo.to(self.prev_token.span),
2117 ident: Some(name),
2118 vis,
2119 safety,
2120 id: DUMMY_NODE_ID,
2121 ty,
2122 default,
2123 attrs,
2124 is_placeholder: false,
2125 })
2126 }
2127
2128 fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2131 let (ident, is_raw) = self.ident_or_err(true)?;
2132 if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
2133 let snapshot = self.create_snapshot_for_diagnostic();
2134 let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2135 let inherited_vis =
2136 Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
2137 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
2139 match self.parse_fn(
2140 &mut AttrVec::new(),
2141 fn_parse_mode,
2142 lo,
2143 &inherited_vis,
2144 Case::Insensitive,
2145 ) {
2146 Ok(_) => {
2147 self.dcx().struct_span_err(
2148 lo.to(self.prev_token.span),
2149 format!("functions are not allowed in {adt_ty} definitions"),
2150 )
2151 .with_help(
2152 "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2153 )
2154 .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information")
2155 }
2156 Err(err) => {
2157 err.cancel();
2158 self.restore_snapshot(snapshot);
2159 self.expected_ident_found_err()
2160 }
2161 }
2162 } else if self.eat_keyword(exp!(Struct)) {
2163 match self.parse_item_struct() {
2164 Ok(item) => {
2165 let ItemKind::Struct(ident, ..) = item else { unreachable!() };
2166 self.dcx()
2167 .struct_span_err(
2168 lo.with_hi(ident.span.hi()),
2169 format!("structs are not allowed in {adt_ty} definitions"),
2170 )
2171 .with_help(
2172 "consider creating a new `struct` definition instead of nesting",
2173 )
2174 }
2175 Err(err) => {
2176 err.cancel();
2177 self.restore_snapshot(snapshot);
2178 self.expected_ident_found_err()
2179 }
2180 }
2181 } else {
2182 let mut err = self.expected_ident_found_err();
2183 if self.eat_keyword_noexpect(kw::Let)
2184 && let removal_span = self.prev_token.span.until(self.token.span)
2185 && let Ok(ident) = self
2186 .parse_ident_common(false)
2187 .map_err(|err| err.cancel())
2189 && self.token == TokenKind::Colon
2190 {
2191 err.span_suggestion(
2192 removal_span,
2193 "remove this `let` keyword",
2194 String::new(),
2195 Applicability::MachineApplicable,
2196 );
2197 err.note("the `let` keyword is not allowed in `struct` fields");
2198 err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
2199 err.emit();
2200 return Ok(ident);
2201 } else {
2202 self.restore_snapshot(snapshot);
2203 }
2204 err
2205 };
2206 return Err(err);
2207 }
2208 self.bump();
2209 Ok(ident)
2210 }
2211
2212 fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2220 let ident = self.parse_ident()?;
2221 let body = if self.check(exp!(OpenBrace)) {
2222 self.parse_delim_args()? } else if self.check(exp!(OpenParen)) {
2224 let params = self.parse_token_tree(); let pspan = params.span();
2226 if !self.check(exp!(OpenBrace)) {
2227 self.unexpected()?;
2228 }
2229 let body = self.parse_token_tree(); let bspan = body.span();
2232 let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); let tokens = TokenStream::new(vec![params, arrow, body]);
2234 let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2235 Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2236 } else {
2237 self.unexpected_any()?
2238 };
2239
2240 self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2241 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false }))
2242 }
2243
2244 fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2246 if self.check_keyword(exp!(MacroRules)) {
2247 let macro_rules_span = self.token.span;
2248
2249 if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2250 return IsMacroRulesItem::Yes { has_bang: true };
2251 } else if self.look_ahead(1, |t| t.is_ident()) {
2252 self.dcx().emit_err(errors::MacroRulesMissingBang {
2254 span: macro_rules_span,
2255 hi: macro_rules_span.shrink_to_hi(),
2256 });
2257
2258 return IsMacroRulesItem::Yes { has_bang: false };
2259 }
2260 }
2261
2262 IsMacroRulesItem::No
2263 }
2264
2265 fn parse_item_macro_rules(
2267 &mut self,
2268 vis: &Visibility,
2269 has_bang: bool,
2270 ) -> PResult<'a, ItemKind> {
2271 self.expect_keyword(exp!(MacroRules))?; if has_bang {
2274 self.expect(exp!(Bang))?; }
2276 let ident = self.parse_ident()?;
2277
2278 if self.eat(exp!(Bang)) {
2279 let span = self.prev_token.span;
2281 self.dcx().emit_err(errors::MacroNameRemoveBang { span });
2282 }
2283
2284 let body = self.parse_delim_args()?;
2285 self.eat_semi_for_macro_if_needed(&body);
2286 self.complain_if_pub_macro(vis, true);
2287
2288 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true }))
2289 }
2290
2291 fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
2294 if let VisibilityKind::Inherited = vis.kind {
2295 return;
2296 }
2297
2298 let vstr = pprust::vis_to_string(vis);
2299 let vstr = vstr.trim_end();
2300 if macro_rules {
2301 self.dcx().emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
2302 } else {
2303 self.dcx().emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
2304 }
2305 }
2306
2307 fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) {
2308 if args.need_semicolon() && !self.eat(exp!(Semi)) {
2309 self.report_invalid_macro_expansion_item(args);
2310 }
2311 }
2312
2313 fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) {
2314 let span = args.dspan.entire();
2315 let mut err = self.dcx().struct_span_err(
2316 span,
2317 "macros that expand to items must be delimited with braces or followed by a semicolon",
2318 );
2319 if !span.from_expansion() {
2322 let DelimSpan { open, close } = args.dspan;
2323 err.multipart_suggestion(
2324 "change the delimiters to curly braces",
2325 vec![(open, "{".to_string()), (close, '}'.to_string())],
2326 Applicability::MaybeIncorrect,
2327 );
2328 err.span_suggestion(
2329 span.with_neighbor(self.token.span).shrink_to_hi(),
2330 "add a semicolon",
2331 ';',
2332 Applicability::MaybeIncorrect,
2333 );
2334 }
2335 err.emit();
2336 }
2337
2338 fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
2341 if (self.token.is_keyword(kw::Enum)
2342 || self.token.is_keyword(kw::Struct)
2343 || self.token.is_keyword(kw::Union))
2344 && self.look_ahead(1, |t| t.is_ident())
2345 {
2346 let kw_token = self.token;
2347 let kw_str = pprust::token_to_string(&kw_token);
2348 let item = self.parse_item(ForceCollect::No)?;
2349 let mut item = item.unwrap().span;
2350 if self.token == token::Comma {
2351 item = item.to(self.token.span);
2352 }
2353 self.dcx().emit_err(errors::NestedAdt {
2354 span: kw_token.span,
2355 item,
2356 kw_str,
2357 keyword: keyword.as_str(),
2358 });
2359 return Ok(false);
2361 }
2362 Ok(true)
2363 }
2364}
2365
2366type ReqName = fn(Edition) -> bool;
2373
2374#[derive(Clone, Copy)]
2382pub(crate) struct FnParseMode {
2383 pub(super) req_name: ReqName,
2406 pub(super) req_body: bool,
2425}
2426
2427impl<'a> Parser<'a> {
2429 fn parse_fn(
2431 &mut self,
2432 attrs: &mut AttrVec,
2433 fn_parse_mode: FnParseMode,
2434 sig_lo: Span,
2435 vis: &Visibility,
2436 case: Case,
2437 ) -> PResult<'a, (Ident, FnSig, Generics, Option<Box<FnContract>>, Option<Box<Block>>)> {
2438 let fn_span = self.token.span;
2439 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(
2443 fn_parse_mode.req_name,
2444 AllowPlus::Yes,
2445 RecoverReturnSign::Yes,
2446 ) {
2447 Ok(decl) => decl,
2448 Err(old_err) => {
2449 if self.token.is_keyword(kw::For) {
2451 old_err.cancel();
2452 return Err(self.dcx().create_err(errors::FnTypoWithImpl { fn_span }));
2453 } else {
2454 return Err(old_err);
2455 }
2456 }
2457 };
2458
2459 let fn_params_end = self.prev_token.span.shrink_to_hi();
2462
2463 let contract = self.parse_contract()?;
2464
2465 generics.where_clause = self.parse_where_clause()?; let fn_params_end =
2469 if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2470
2471 let mut sig_hi = self.prev_token.span;
2472 let body =
2474 self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
2475 let fn_sig_span = sig_lo.to(sig_hi);
2476 Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
2477 }
2478
2479 fn error_fn_body_not_found(
2481 &mut self,
2482 ident_span: Span,
2483 req_body: bool,
2484 fn_params_end: Option<Span>,
2485 ) -> PResult<'a, ErrorGuaranteed> {
2486 let expected: &[_] =
2487 if req_body { &[exp!(OpenBrace)] } else { &[exp!(Semi), exp!(OpenBrace)] };
2488 match self.expected_one_of_not_found(&[], expected) {
2489 Ok(error_guaranteed) => Ok(error_guaranteed),
2490 Err(mut err) => {
2491 if self.token == token::CloseBrace {
2492 err.span_label(ident_span, "while parsing this `fn`");
2495 Ok(err.emit())
2496 } else if self.token == token::RArrow
2497 && let Some(fn_params_end) = fn_params_end
2498 {
2499 let fn_trait_span =
2505 [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2506 if self.prev_token.is_ident_named(symbol) {
2507 Some(self.prev_token.span)
2508 } else {
2509 None
2510 }
2511 });
2512
2513 let arrow_span = self.token.span;
2518 let ty_span = match self.parse_ret_ty(
2519 AllowPlus::Yes,
2520 RecoverQPath::Yes,
2521 RecoverReturnSign::Yes,
2522 ) {
2523 Ok(ty_span) => ty_span.span().shrink_to_hi(),
2524 Err(parse_error) => {
2525 parse_error.cancel();
2526 return Err(err);
2527 }
2528 };
2529 let ret_ty_span = arrow_span.to(ty_span);
2530
2531 if let Some(fn_trait_span) = fn_trait_span {
2532 err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2535 } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2536 {
2537 err.primary_message(
2541 "return type should be specified after the function parameters",
2542 );
2543 err.subdiagnostic(errors::MisplacedReturnType {
2544 fn_params_end,
2545 snippet,
2546 ret_ty_span,
2547 });
2548 }
2549 Err(err)
2550 } else {
2551 Err(err)
2552 }
2553 }
2554 }
2555 }
2556
2557 fn parse_fn_body(
2561 &mut self,
2562 attrs: &mut AttrVec,
2563 ident: &Ident,
2564 sig_hi: &mut Span,
2565 req_body: bool,
2566 fn_params_end: Option<Span>,
2567 ) -> PResult<'a, Option<Box<Block>>> {
2568 let has_semi = if req_body {
2569 self.token == TokenKind::Semi
2570 } else {
2571 self.check(exp!(Semi))
2573 };
2574 let (inner_attrs, body) = if has_semi {
2575 self.expect_semi()?;
2577 *sig_hi = self.prev_token.span;
2578 (AttrVec::new(), None)
2579 } else if self.check(exp!(OpenBrace)) || self.token.is_metavar_block() {
2580 self.parse_block_common(self.token.span, BlockCheckMode::Default, None)
2581 .map(|(attrs, body)| (attrs, Some(body)))?
2582 } else if self.token == token::Eq {
2583 self.bump(); let eq_sp = self.prev_token.span;
2586 let _ = self.parse_expr()?;
2587 self.expect_semi()?; let span = eq_sp.to(self.prev_token.span);
2589 let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
2590 span,
2591 sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
2592 });
2593 (AttrVec::new(), Some(self.mk_block_err(span, guar)))
2594 } else {
2595 self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
2596 (AttrVec::new(), None)
2597 };
2598 attrs.extend(inner_attrs);
2599 Ok(body)
2600 }
2601
2602 pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
2607 const ALL_QUALS: &[ExpKeywordPair] = &[
2608 exp!(Pub),
2609 exp!(Gen),
2610 exp!(Const),
2611 exp!(Async),
2612 exp!(Unsafe),
2613 exp!(Safe),
2614 exp!(Extern),
2615 ];
2616
2617 let quals: &[_] = if check_pub {
2622 ALL_QUALS
2623 } else {
2624 &[exp!(Gen), exp!(Const), exp!(Async), exp!(Unsafe), exp!(Safe), exp!(Extern)]
2625 };
2626 self.check_keyword_case(exp!(Fn), case) || quals.iter().any(|&exp| self.check_keyword_case(exp, case))
2629 && self.look_ahead(1, |t| {
2630 t.is_keyword_case(kw::Fn, case)
2632 || (
2634 (
2635 t.is_non_raw_ident_where(|i|
2636 quals.iter().any(|exp| exp.kw == i.name)
2637 && i.is_reserved()
2639 )
2640 || case == Case::Insensitive
2641 && t.is_non_raw_ident_where(|i| quals.iter().any(|exp| {
2642 exp.kw.as_str() == i.name.as_str().to_lowercase()
2643 }))
2644 )
2645 && !self.is_unsafe_foreign_mod()
2647 && !self.is_async_gen_block())
2649 })
2650 || self.check_keyword_case(exp!(Extern), case)
2652 && self.look_ahead(1, |t| t.can_begin_string_literal())
2656 && (self.tree_look_ahead(2, |tt| {
2657 match tt {
2658 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2659 TokenTree::Delimited(..) => false,
2660 }
2661 }) == Some(true) ||
2662 (self.may_recover()
2665 && self.tree_look_ahead(2, |tt| {
2666 match tt {
2667 TokenTree::Token(t, _) =>
2668 ALL_QUALS.iter().any(|exp| {
2669 t.is_keyword(exp.kw)
2670 }),
2671 TokenTree::Delimited(..) => false,
2672 }
2673 }) == Some(true)
2674 && self.tree_look_ahead(3, |tt| {
2675 match tt {
2676 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2677 TokenTree::Delimited(..) => false,
2678 }
2679 }) == Some(true)
2680 )
2681 )
2682 }
2683
2684 pub(super) fn parse_fn_front_matter(
2699 &mut self,
2700 orig_vis: &Visibility,
2701 case: Case,
2702 parsing_mode: FrontMatterParsingMode,
2703 ) -> PResult<'a, FnHeader> {
2704 let sp_start = self.token.span;
2705 let constness = self.parse_constness(case);
2706 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2707 && let Const::Yes(const_span) = constness
2708 {
2709 self.dcx().emit_err(FnPointerCannotBeConst {
2710 span: const_span,
2711 suggestion: const_span.until(self.token.span),
2712 });
2713 }
2714
2715 let async_start_sp = self.token.span;
2716 let coroutine_kind = self.parse_coroutine_kind(case);
2717 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2718 && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind
2719 {
2720 self.dcx().emit_err(FnPointerCannotBeAsync {
2721 span: async_span,
2722 suggestion: async_span.until(self.token.span),
2723 });
2724 }
2725 let unsafe_start_sp = self.token.span;
2728 let safety = self.parse_safety(case);
2729
2730 let ext_start_sp = self.token.span;
2731 let ext = self.parse_extern(case);
2732
2733 if let Some(CoroutineKind::Async { span, .. }) = coroutine_kind {
2734 if span.is_rust_2015() {
2735 self.dcx().emit_err(errors::AsyncFnIn2015 {
2736 span,
2737 help: errors::HelpUseLatestEdition::new(),
2738 });
2739 }
2740 }
2741
2742 match coroutine_kind {
2743 Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
2744 self.psess.gated_spans.gate(sym::gen_blocks, span);
2745 }
2746 Some(CoroutineKind::Async { .. }) | None => {}
2747 }
2748
2749 if !self.eat_keyword_case(exp!(Fn), case) {
2750 match self.expect_one_of(&[], &[]) {
2754 Ok(Recovered::Yes(_)) => {}
2755 Ok(Recovered::No) => unreachable!(),
2756 Err(mut err) => {
2757 enum WrongKw {
2759 Duplicated(Span),
2760 Misplaced(Span),
2761 MisplacedDisallowedQualifier,
2766 }
2767
2768 let mut recover_constness = constness;
2770 let mut recover_coroutine_kind = coroutine_kind;
2771 let mut recover_safety = safety;
2772 let wrong_kw = if self.check_keyword(exp!(Const)) {
2775 match constness {
2776 Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
2777 Const::No => {
2778 recover_constness = Const::Yes(self.token.span);
2779 match parsing_mode {
2780 FrontMatterParsingMode::Function => {
2781 Some(WrongKw::Misplaced(async_start_sp))
2782 }
2783 FrontMatterParsingMode::FunctionPtrType => {
2784 self.dcx().emit_err(FnPointerCannotBeConst {
2785 span: self.token.span,
2786 suggestion: self
2787 .token
2788 .span
2789 .with_lo(self.prev_token.span.hi()),
2790 });
2791 Some(WrongKw::MisplacedDisallowedQualifier)
2792 }
2793 }
2794 }
2795 }
2796 } else if self.check_keyword(exp!(Async)) {
2797 match coroutine_kind {
2798 Some(CoroutineKind::Async { span, .. }) => {
2799 Some(WrongKw::Duplicated(span))
2800 }
2801 Some(CoroutineKind::AsyncGen { span, .. }) => {
2802 Some(WrongKw::Duplicated(span))
2803 }
2804 Some(CoroutineKind::Gen { .. }) => {
2805 recover_coroutine_kind = Some(CoroutineKind::AsyncGen {
2806 span: self.token.span,
2807 closure_id: DUMMY_NODE_ID,
2808 return_impl_trait_id: DUMMY_NODE_ID,
2809 });
2810 Some(WrongKw::Misplaced(unsafe_start_sp))
2812 }
2813 None => {
2814 recover_coroutine_kind = Some(CoroutineKind::Async {
2815 span: self.token.span,
2816 closure_id: DUMMY_NODE_ID,
2817 return_impl_trait_id: DUMMY_NODE_ID,
2818 });
2819 match parsing_mode {
2820 FrontMatterParsingMode::Function => {
2821 Some(WrongKw::Misplaced(async_start_sp))
2822 }
2823 FrontMatterParsingMode::FunctionPtrType => {
2824 self.dcx().emit_err(FnPointerCannotBeAsync {
2825 span: self.token.span,
2826 suggestion: self
2827 .token
2828 .span
2829 .with_lo(self.prev_token.span.hi()),
2830 });
2831 Some(WrongKw::MisplacedDisallowedQualifier)
2832 }
2833 }
2834 }
2835 }
2836 } else if self.check_keyword(exp!(Unsafe)) {
2837 match safety {
2838 Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
2839 Safety::Safe(sp) => {
2840 recover_safety = Safety::Unsafe(self.token.span);
2841 Some(WrongKw::Misplaced(sp))
2842 }
2843 Safety::Default => {
2844 recover_safety = Safety::Unsafe(self.token.span);
2845 Some(WrongKw::Misplaced(ext_start_sp))
2846 }
2847 }
2848 } else if self.check_keyword(exp!(Safe)) {
2849 match safety {
2850 Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
2851 Safety::Unsafe(sp) => {
2852 recover_safety = Safety::Safe(self.token.span);
2853 Some(WrongKw::Misplaced(sp))
2854 }
2855 Safety::Default => {
2856 recover_safety = Safety::Safe(self.token.span);
2857 Some(WrongKw::Misplaced(ext_start_sp))
2858 }
2859 }
2860 } else {
2861 None
2862 };
2863
2864 if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw {
2866 let original_kw = self
2867 .span_to_snippet(original_sp)
2868 .expect("Span extracted directly from keyword should always work");
2869
2870 err.span_suggestion(
2871 self.token_uninterpolated_span(),
2872 format!("`{original_kw}` already used earlier, remove this one"),
2873 "",
2874 Applicability::MachineApplicable,
2875 )
2876 .span_note(original_sp, format!("`{original_kw}` first seen here"));
2877 }
2878 else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
2880 let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
2881 if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
2882 let misplaced_qual_sp = self.token_uninterpolated_span();
2883 let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
2884
2885 err.span_suggestion(
2886 correct_pos_sp.to(misplaced_qual_sp),
2887 format!("`{misplaced_qual}` must come before `{current_qual}`"),
2888 format!("{misplaced_qual} {current_qual}"),
2889 Applicability::MachineApplicable,
2890 ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
2891 }
2892 }
2893 else if self.check_keyword(exp!(Pub)) {
2895 let sp = sp_start.to(self.prev_token.span);
2896 if let Ok(snippet) = self.span_to_snippet(sp) {
2897 let current_vis = match self.parse_visibility(FollowedByType::No) {
2898 Ok(v) => v,
2899 Err(d) => {
2900 d.cancel();
2901 return Err(err);
2902 }
2903 };
2904 let vs = pprust::vis_to_string(¤t_vis);
2905 let vs = vs.trim_end();
2906
2907 if matches!(orig_vis.kind, VisibilityKind::Inherited) {
2909 err.span_suggestion(
2910 sp_start.to(self.prev_token.span),
2911 format!("visibility `{vs}` must come before `{snippet}`"),
2912 format!("{vs} {snippet}"),
2913 Applicability::MachineApplicable,
2914 );
2915 }
2916 else {
2918 err.span_suggestion(
2919 current_vis.span,
2920 "there is already a visibility modifier, remove one",
2921 "",
2922 Applicability::MachineApplicable,
2923 )
2924 .span_note(orig_vis.span, "explicit visibility first seen here");
2925 }
2926 }
2927 }
2928
2929 if let Some(wrong_kw) = wrong_kw
2932 && self.may_recover()
2933 && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
2934 {
2935 self.bump();
2937 self.bump();
2938 if matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) {
2941 err.cancel();
2942 } else {
2943 err.emit();
2944 }
2945 return Ok(FnHeader {
2946 constness: recover_constness,
2947 safety: recover_safety,
2948 coroutine_kind: recover_coroutine_kind,
2949 ext,
2950 });
2951 }
2952
2953 return Err(err);
2954 }
2955 }
2956 }
2957
2958 Ok(FnHeader { constness, safety, coroutine_kind, ext })
2959 }
2960
2961 pub(super) fn parse_fn_decl(
2963 &mut self,
2964 req_name: ReqName,
2965 ret_allow_plus: AllowPlus,
2966 recover_return_sign: RecoverReturnSign,
2967 ) -> PResult<'a, Box<FnDecl>> {
2968 Ok(Box::new(FnDecl {
2969 inputs: self.parse_fn_params(req_name)?,
2970 output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
2971 }))
2972 }
2973
2974 pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinVec<Param>> {
2976 let mut first_param = true;
2977 if self.token != TokenKind::OpenParen
2979 && !self.token.is_keyword(kw::For)
2981 {
2982 self.dcx()
2984 .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() });
2985 return Ok(ThinVec::new());
2986 }
2987
2988 let (mut params, _) = self.parse_paren_comma_seq(|p| {
2989 p.recover_vcs_conflict_marker();
2990 let snapshot = p.create_snapshot_for_diagnostic();
2991 let param = p.parse_param_general(req_name, first_param, true).or_else(|e| {
2992 let guar = e.emit();
2993 let lo = if let TokenKind::OpenParen = p.prev_token.kind {
2997 p.prev_token.span.shrink_to_hi()
2998 } else {
2999 p.prev_token.span
3000 };
3001 p.restore_snapshot(snapshot);
3002 p.eat_to_tokens(&[exp!(Comma), exp!(CloseParen)]);
3004 Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
3006 });
3007 first_param = false;
3009 param
3010 })?;
3011 self.deduplicate_recovered_params_names(&mut params);
3013 Ok(params)
3014 }
3015
3016 pub(super) fn parse_param_general(
3021 &mut self,
3022 req_name: ReqName,
3023 first_param: bool,
3024 recover_arg_parse: bool,
3025 ) -> PResult<'a, Param> {
3026 let lo = self.token.span;
3027 let attrs = self.parse_outer_attributes()?;
3028 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
3029 if let Some(mut param) = this.parse_self_param()? {
3031 param.attrs = attrs;
3032 let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
3033 return Ok((res?, Trailing::No, UsePreAttrPos::No));
3034 }
3035
3036 let is_name_required = match this.token.kind {
3037 token::DotDotDot => false,
3038 _ => req_name(this.token.span.with_neighbor(this.prev_token.span).edition()),
3039 };
3040 let (pat, ty) = if is_name_required || this.is_named_param() {
3041 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
3042 let (pat, colon) = this.parse_fn_param_pat_colon()?;
3043 if !colon {
3044 let mut err = this.unexpected().unwrap_err();
3045 return if let Some(ident) =
3046 this.parameter_without_type(&mut err, pat, is_name_required, first_param)
3047 {
3048 let guar = err.emit();
3049 Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No))
3050 } else {
3051 Err(err)
3052 };
3053 }
3054
3055 this.eat_incorrect_doc_comment_for_param_type();
3056 (pat, this.parse_ty_for_param()?)
3057 } else {
3058 debug!("parse_param_general ident_to_pat");
3059 let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
3060 this.eat_incorrect_doc_comment_for_param_type();
3061 let mut ty = this.parse_ty_for_param();
3062
3063 if let Ok(t) = &ty {
3064 if let TyKind::Path(_, Path { segments, .. }) = &t.kind
3066 && let Some(segment) = segments.last()
3067 && let Some(guar) =
3068 this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
3069 {
3070 return Ok((
3071 dummy_arg(segment.ident, guar),
3072 Trailing::No,
3073 UsePreAttrPos::No,
3074 ));
3075 }
3076
3077 if this.token != token::Comma && this.token != token::CloseParen {
3078 ty = this.unexpected_any();
3081 }
3082 }
3083 match ty {
3084 Ok(ty) => {
3085 let pat = this.mk_pat(ty.span, PatKind::Missing);
3086 (pat, ty)
3087 }
3088 Err(err) if this.token == token::DotDotDot => return Err(err),
3090 Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
3091 Err(err) if recover_arg_parse => {
3092 err.cancel();
3094 this.restore_snapshot(parser_snapshot_before_ty);
3095 this.recover_arg_parse()?
3096 }
3097 Err(err) => return Err(err),
3098 }
3099 };
3100
3101 let span = lo.to(this.prev_token.span);
3102
3103 Ok((
3104 Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
3105 Trailing::No,
3106 UsePreAttrPos::No,
3107 ))
3108 })
3109 }
3110
3111 fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
3113 let expect_self_ident = |this: &mut Self| match this.token.ident() {
3115 Some((ident, IdentIsRaw::No)) => {
3116 this.bump();
3117 ident
3118 }
3119 _ => unreachable!(),
3120 };
3121 let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
3123 let is_isolated_self = |this: &Self, n| {
3125 this.is_keyword_ahead(n, &[kw::SelfLower])
3126 && this.look_ahead(n + 1, |t| t != &token::PathSep)
3127 };
3128 let is_isolated_pin_const_self = |this: &Self, n| {
3130 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3131 && this.is_keyword_ahead(n + 1, &[kw::Const])
3132 && is_isolated_self(this, n + 2)
3133 };
3134 let is_isolated_mut_self =
3136 |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
3137 let is_isolated_pin_mut_self = |this: &Self, n| {
3139 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3140 && is_isolated_mut_self(this, n + 1)
3141 };
3142 let parse_self_possibly_typed = |this: &mut Self, m| {
3144 let eself_ident = expect_self_ident(this);
3145 let eself_hi = this.prev_token.span;
3146 let eself = if this.eat(exp!(Colon)) {
3147 SelfKind::Explicit(this.parse_ty()?, m)
3148 } else {
3149 SelfKind::Value(m)
3150 };
3151 Ok((eself, eself_ident, eself_hi))
3152 };
3153 let expect_self_ident_not_typed =
3154 |this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
3155 let eself_ident = expect_self_ident(this);
3156
3157 if this.may_recover() && this.eat_noexpect(&token::Colon) {
3159 let snap = this.create_snapshot_for_diagnostic();
3160 match this.parse_ty() {
3161 Ok(ty) => {
3162 this.dcx().emit_err(errors::IncorrectTypeOnSelf {
3163 span: ty.span,
3164 move_self_modifier: errors::MoveSelfModifier {
3165 removal_span: modifier_span,
3166 insertion_span: ty.span.shrink_to_lo(),
3167 modifier: modifier.to_ref_suggestion(),
3168 },
3169 });
3170 }
3171 Err(diag) => {
3172 diag.cancel();
3173 this.restore_snapshot(snap);
3174 }
3175 }
3176 }
3177 eself_ident
3178 };
3179 let recover_self_ptr = |this: &mut Self| {
3181 this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
3182
3183 Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
3184 };
3185
3186 let eself_lo = self.token.span;
3190 let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
3191 token::And => {
3192 let has_lifetime = is_lifetime(self, 1);
3193 let skip_lifetime_count = has_lifetime as usize;
3194 let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3195 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3198 SelfKind::Region(lifetime, Mutability::Not)
3199 } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3200 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3203 self.bump(); SelfKind::Region(lifetime, Mutability::Mut)
3205 } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3206 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3209 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3210 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Not)
3213 } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
3214 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3217 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3218 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Mut)
3221 } else {
3222 return Ok(None);
3224 };
3225 let hi = self.token.span;
3226 let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3227 (eself, self_ident, hi)
3228 }
3229 token::Star if is_isolated_self(self, 1) => {
3231 self.bump();
3232 recover_self_ptr(self)?
3233 }
3234 token::Star
3236 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
3237 {
3238 self.bump();
3239 self.bump();
3240 recover_self_ptr(self)?
3241 }
3242 token::Ident(..) if is_isolated_self(self, 0) => {
3244 parse_self_possibly_typed(self, Mutability::Not)?
3245 }
3246 token::Ident(..) if is_isolated_mut_self(self, 0) => {
3248 self.bump();
3249 parse_self_possibly_typed(self, Mutability::Mut)?
3250 }
3251 _ => return Ok(None),
3252 };
3253
3254 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
3255 Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
3256 }
3257
3258 fn is_named_param(&self) -> bool {
3259 let offset = match &self.token.kind {
3260 token::OpenInvisible(origin) => match origin {
3261 InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
3262 return self.check_noexpect_past_close_delim(&token::Colon);
3263 }
3264 _ => 0,
3265 },
3266 token::And | token::AndAnd => 1,
3267 _ if self.token.is_keyword(kw::Mut) => 1,
3268 _ => 0,
3269 };
3270
3271 self.look_ahead(offset, |t| t.is_ident())
3272 && self.look_ahead(offset + 1, |t| t == &token::Colon)
3273 }
3274
3275 fn recover_self_param(&mut self) -> bool {
3276 matches!(
3277 self.parse_outer_attributes()
3278 .and_then(|_| self.parse_self_param())
3279 .map_err(|e| e.cancel()),
3280 Ok(Some(_))
3281 )
3282 }
3283}
3284
3285enum IsMacroRulesItem {
3286 Yes { has_bang: bool },
3287 No,
3288}
3289
3290#[derive(Copy, Clone, PartialEq, Eq)]
3291pub(super) enum FrontMatterParsingMode {
3292 Function,
3294 FunctionPtrType,
3297}