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 let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
254 if self.token.is_keyword(kw::Impl) {
256 self.recover_const_impl(const_span, attrs, def_())?
258 } else {
259 self.recover_const_mut(const_span);
260 self.recover_missing_kw_before_item()?;
261 let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?;
262 ItemKind::Const(Box::new(ConstItem {
263 defaultness: def_(),
264 ident,
265 generics,
266 ty,
267 rhs,
268 define_opaque: None,
269 }))
270 }
271 } else if self.check_keyword(exp!(Impl))
272 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Impl])
273 {
274 self.parse_item_impl(attrs, def_())?
276 } else if self.is_reuse_path_item() {
277 self.parse_item_delegation()?
278 } else if self.check_keyword(exp!(Mod))
279 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Mod])
280 {
281 self.parse_item_mod(attrs)?
283 } else if self.eat_keyword(exp!(Type)) {
284 self.parse_type_alias(def_())?
286 } else if self.eat_keyword(exp!(Enum)) {
287 self.parse_item_enum()?
289 } else if self.eat_keyword(exp!(Struct)) {
290 self.parse_item_struct()?
292 } else if self.is_kw_followed_by_ident(kw::Union) {
293 self.bump(); self.parse_item_union()?
296 } else if self.is_builtin() {
297 return self.parse_item_builtin();
299 } else if self.eat_keyword(exp!(Macro)) {
300 self.parse_item_decl_macro(lo)?
302 } else if let IsMacroRulesItem::Yes { has_bang } = self.is_macro_rules_item() {
303 self.parse_item_macro_rules(vis, has_bang)?
305 } else if self.isnt_macro_invocation()
306 && (self.token.is_ident_named(sym::import)
307 || self.token.is_ident_named(sym::using)
308 || self.token.is_ident_named(sym::include)
309 || self.token.is_ident_named(sym::require))
310 {
311 return self.recover_import_as_use();
312 } else if self.isnt_macro_invocation() && vis.kind.is_pub() {
313 self.recover_missing_kw_before_item()?;
314 return Ok(None);
315 } else if self.isnt_macro_invocation() && case == Case::Sensitive {
316 _ = def_;
317
318 return self.parse_item_kind(
320 attrs,
321 macros_allowed,
322 lo,
323 vis,
324 def,
325 fn_parse_mode,
326 Case::Insensitive,
327 );
328 } else if macros_allowed && self.check_path() {
329 if self.isnt_macro_invocation() {
330 self.recover_missing_kw_before_item()?;
331 }
332 ItemKind::MacCall(Box::new(self.parse_item_macro(vis)?))
334 } else {
335 return Ok(None);
336 };
337 Ok(Some(info))
338 }
339
340 fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
341 let span = self.token.span;
342 let token_name = super::token_descr(&self.token);
343 let snapshot = self.create_snapshot_for_diagnostic();
344 self.bump();
345 match self.parse_use_item() {
346 Ok(u) => {
347 self.dcx().emit_err(errors::RecoverImportAsUse { span, token_name });
348 Ok(Some(u))
349 }
350 Err(e) => {
351 e.cancel();
352 self.restore_snapshot(snapshot);
353 Ok(None)
354 }
355 }
356 }
357
358 fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
359 let tree = self.parse_use_tree()?;
360 if let Err(mut e) = self.expect_semi() {
361 match tree.kind {
362 UseTreeKind::Glob => {
363 e.note("the wildcard token must be last on the path");
364 }
365 UseTreeKind::Nested { .. } => {
366 e.note("glob-like brace syntax must be last on the path");
367 }
368 _ => (),
369 }
370 return Err(e);
371 }
372 Ok(ItemKind::Use(tree))
373 }
374
375 pub(super) fn is_path_start_item(&mut self) -> bool {
377 self.is_kw_followed_by_ident(kw::Union) || self.is_reuse_path_item()
379 || self.check_trait_front_matter() || self.is_async_fn() || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) }
383
384 fn is_reuse_path_item(&mut self) -> bool {
385 self.token.is_keyword(kw::Reuse)
387 && self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep)
388 }
389
390 fn isnt_macro_invocation(&mut self) -> bool {
392 self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep)
393 }
394
395 fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
398 let is_pub = self.prev_token.is_keyword(kw::Pub);
399 let is_const = self.prev_token.is_keyword(kw::Const);
400 let ident_span = self.token.span;
401 let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span };
402 let insert_span = ident_span.shrink_to_lo();
403
404 let ident = if self.token.is_ident()
405 && (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
406 && self.look_ahead(1, |t| {
407 matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen)
408 }) {
409 self.parse_ident().unwrap()
410 } else {
411 return Ok(());
412 };
413
414 let mut found_generics = false;
415 if self.check(exp!(Lt)) {
416 found_generics = true;
417 self.eat_to_tokens(&[exp!(Gt)]);
418 self.bump(); }
420
421 let err = if self.check(exp!(OpenBrace)) {
422 if self.look_ahead(1, |t| *t == token::CloseBrace) {
424 Some(errors::MissingKeywordForItemDefinition::EnumOrStruct { span })
426 } else if self.look_ahead(2, |t| *t == token::Colon)
427 || self.look_ahead(3, |t| *t == token::Colon)
428 {
429 Some(errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident })
431 } else {
432 Some(errors::MissingKeywordForItemDefinition::Enum { span, insert_span, ident })
433 }
434 } else if self.check(exp!(OpenParen)) {
435 self.bump(); let is_method = self.recover_self_param();
438
439 self.consume_block(exp!(OpenParen), exp!(CloseParen), ConsumeClosingDelim::Yes);
440
441 let err = if self.check(exp!(RArrow)) || self.check(exp!(OpenBrace)) {
442 self.eat_to_tokens(&[exp!(OpenBrace)]);
443 self.bump(); self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
445 if is_method {
446 errors::MissingKeywordForItemDefinition::Method { span, insert_span, ident }
447 } else {
448 errors::MissingKeywordForItemDefinition::Function { span, insert_span, ident }
449 }
450 } else if is_pub && self.check(exp!(Semi)) {
451 errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident }
452 } else {
453 errors::MissingKeywordForItemDefinition::Ambiguous {
454 span,
455 subdiag: if found_generics {
456 None
457 } else if let Ok(snippet) = self.span_to_snippet(ident_span) {
458 Some(errors::AmbiguousMissingKwForItemSub::SuggestMacro {
459 span: ident_span,
460 snippet,
461 })
462 } else {
463 Some(errors::AmbiguousMissingKwForItemSub::HelpMacro)
464 },
465 }
466 };
467 Some(err)
468 } else if found_generics {
469 Some(errors::MissingKeywordForItemDefinition::Ambiguous { span, subdiag: None })
470 } else {
471 None
472 };
473
474 if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
475 }
476
477 fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemKind>> {
478 Ok(None)
480 }
481
482 fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
484 let path = self.parse_path(PathStyle::Mod)?; self.expect(exp!(Bang))?; match self.parse_delim_args() {
487 Ok(args) => {
489 self.eat_semi_for_macro_if_needed(&args);
490 self.complain_if_pub_macro(vis, false);
491 Ok(MacCall { path, args })
492 }
493
494 Err(mut err) => {
495 if self.token.is_ident()
497 && let [segment] = path.segments.as_slice()
498 && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some()
499 {
500 err.span_suggestion(
501 path.span,
502 "perhaps you meant to define a macro",
503 "macro_rules",
504 Applicability::MachineApplicable,
505 );
506 }
507 Err(err)
508 }
509 }
510 }
511
512 fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
514 let ([start @ end] | [start, .., end]) = attrs else {
515 return Ok(());
516 };
517 let msg = if end.is_doc_comment() {
518 "expected item after doc comment"
519 } else {
520 "expected item after attributes"
521 };
522 let mut err = self.dcx().struct_span_err(end.span, msg);
523 if end.is_doc_comment() {
524 err.span_label(end.span, "this doc comment doesn't document anything");
525 } else if self.token == TokenKind::Semi {
526 err.span_suggestion_verbose(
527 self.token.span,
528 "consider removing this semicolon",
529 "",
530 Applicability::MaybeIncorrect,
531 );
532 }
533 if let [.., penultimate, _] = attrs {
534 err.span_label(start.span.to(penultimate.span), "other attributes here");
535 }
536 Err(err)
537 }
538
539 fn is_async_fn(&self) -> bool {
540 self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
541 }
542
543 fn parse_polarity(&mut self) -> ast::ImplPolarity {
544 if self.check(exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) {
546 self.bump(); ast::ImplPolarity::Negative(self.prev_token.span)
548 } else {
549 ast::ImplPolarity::Positive
550 }
551 }
552
553 fn parse_item_impl(
568 &mut self,
569 attrs: &mut AttrVec,
570 defaultness: Defaultness,
571 ) -> PResult<'a, ItemKind> {
572 let safety = self.parse_safety(Case::Sensitive);
573 self.expect_keyword(exp!(Impl))?;
574
575 let mut generics = if self.choose_generics_over_qpath(0) {
577 self.parse_generics()?
578 } else {
579 let mut generics = Generics::default();
580 generics.span = self.prev_token.span.shrink_to_hi();
583 generics
584 };
585
586 let constness = self.parse_constness(Case::Sensitive);
587 if let Const::Yes(span) = constness {
588 self.psess.gated_spans.gate(sym::const_trait_impl, span);
589 }
590
591 if (self.token_uninterpolated_span().at_least_rust_2018()
593 && self.token.is_keyword(kw::Async))
594 || self.is_kw_followed_by_ident(kw::Async)
595 {
596 self.bump();
597 self.dcx().emit_err(errors::AsyncImpl { span: self.prev_token.span });
598 }
599
600 let polarity = self.parse_polarity();
601
602 let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
604 {
605 let span = self.prev_token.span.between(self.token.span);
606 return Err(self.dcx().create_err(errors::MissingTraitInTraitImpl {
607 span,
608 for_span: span.to(self.token.span),
609 }));
610 } else {
611 self.parse_ty_with_generics_recovery(&generics)?
612 };
613
614 let has_for = self.eat_keyword(exp!(For));
616 let missing_for_span = self.prev_token.span.between(self.token.span);
617
618 let ty_second = if self.token == token::DotDot {
619 self.bump(); Some(self.mk_ty(self.prev_token.span, TyKind::Dummy))
626 } else if has_for || self.token.can_begin_type() {
627 Some(self.parse_ty()?)
628 } else {
629 None
630 };
631
632 generics.where_clause = self.parse_where_clause()?;
633
634 let impl_items = self.parse_item_list(attrs, |p| p.parse_impl_item(ForceCollect::No))?;
635
636 let (of_trait, self_ty) = match ty_second {
637 Some(ty_second) => {
638 if !has_for {
640 self.dcx().emit_err(errors::MissingForInTraitImpl { span: missing_for_span });
641 }
642
643 let ty_first = *ty_first;
644 let path = match ty_first.kind {
645 TyKind::Path(None, path) => path,
647 other => {
648 if let TyKind::ImplTrait(_, bounds) = other
649 && let [bound] = bounds.as_slice()
650 && let GenericBound::Trait(poly_trait_ref) = bound
651 {
652 let extra_impl_kw = ty_first.span.until(bound.span());
656 self.dcx().emit_err(errors::ExtraImplKeywordInTraitImpl {
657 extra_impl_kw,
658 impl_trait_span: ty_first.span,
659 });
660 poly_trait_ref.trait_ref.path.clone()
661 } else {
662 return Err(self.dcx().create_err(
663 errors::ExpectedTraitInTraitImplFoundType { span: ty_first.span },
664 ));
665 }
666 }
667 };
668 let trait_ref = TraitRef { path, ref_id: ty_first.id };
669
670 let of_trait = Some(Box::new(TraitImplHeader {
671 defaultness,
672 safety,
673 constness,
674 polarity,
675 trait_ref,
676 }));
677 (of_trait, ty_second)
678 }
679 None => {
680 let self_ty = ty_first;
681 let error = |modifier, modifier_name, modifier_span| {
682 self.dcx().create_err(errors::TraitImplModifierInInherentImpl {
683 span: self_ty.span,
684 modifier,
685 modifier_name,
686 modifier_span,
687 self_ty: self_ty.span,
688 })
689 };
690
691 if let Safety::Unsafe(span) = safety {
692 error("unsafe", "unsafe", span).with_code(E0197).emit();
693 }
694 if let ImplPolarity::Negative(span) = polarity {
695 error("!", "negative", span).emit();
696 }
697 if let Defaultness::Default(def_span) = defaultness {
698 error("default", "default", def_span).emit();
699 }
700 if let Const::Yes(span) = constness {
701 error("const", "const", span).emit();
702 }
703 (None, self_ty)
704 }
705 };
706
707 Ok(ItemKind::Impl(Impl { generics, of_trait, self_ty, items: impl_items }))
708 }
709
710 fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> {
711 let span = self.token.span;
712 self.expect_keyword(exp!(Reuse))?;
713
714 let (qself, path) = if self.eat_lt() {
715 let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
716 (Some(qself), path)
717 } else {
718 (None, self.parse_path(PathStyle::Expr)?)
719 };
720
721 let rename = |this: &mut Self| {
722 Ok(if this.eat_keyword(exp!(As)) { Some(this.parse_ident()?) } else { None })
723 };
724 let body = |this: &mut Self| {
725 Ok(if this.check(exp!(OpenBrace)) {
726 Some(this.parse_block()?)
727 } else {
728 this.expect(exp!(Semi))?;
729 None
730 })
731 };
732
733 let item_kind = if self.eat_path_sep() {
734 let suffixes = if self.eat(exp!(Star)) {
735 None
736 } else {
737 let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?));
738 Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0)
739 };
740 let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? };
741 ItemKind::DelegationMac(Box::new(deleg))
742 } else {
743 let rename = rename(self)?;
744 let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
745 let deleg = Delegation {
746 id: DUMMY_NODE_ID,
747 qself,
748 path,
749 ident,
750 rename,
751 body: body(self)?,
752 from_glob: false,
753 };
754 ItemKind::Delegation(Box::new(deleg))
755 };
756
757 let span = span.to(self.prev_token.span);
758 self.psess.gated_spans.gate(sym::fn_delegation, span);
759
760 Ok(item_kind)
761 }
762
763 fn parse_item_list<T>(
764 &mut self,
765 attrs: &mut AttrVec,
766 mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
767 ) -> PResult<'a, ThinVec<T>> {
768 let open_brace_span = self.token.span;
769
770 if self.token == TokenKind::Semi {
772 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
773 self.bump();
774 return Ok(ThinVec::new());
775 }
776
777 self.expect(exp!(OpenBrace))?;
778 attrs.extend(self.parse_inner_attributes()?);
779
780 let mut items = ThinVec::new();
781 while !self.eat(exp!(CloseBrace)) {
782 if self.recover_doc_comment_before_brace() {
783 continue;
784 }
785 self.recover_vcs_conflict_marker();
786 match parse_item(self) {
787 Ok(None) => {
788 let mut is_unnecessary_semicolon = !items.is_empty()
789 && self
807 .span_to_snippet(self.prev_token.span)
808 .is_ok_and(|snippet| snippet == "}")
809 && self.token == token::Semi;
810 let mut semicolon_span = self.token.span;
811 if !is_unnecessary_semicolon {
812 is_unnecessary_semicolon =
814 self.token == token::OpenBrace && self.prev_token == token::Semi;
815 semicolon_span = self.prev_token.span;
816 }
817 let non_item_span = self.token.span;
819 let is_let = self.token.is_keyword(kw::Let);
820
821 let mut err =
822 self.dcx().struct_span_err(non_item_span, "non-item in item list");
823 self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
824 if is_let {
825 err.span_suggestion_verbose(
826 non_item_span,
827 "consider using `const` instead of `let` for associated const",
828 "const",
829 Applicability::MachineApplicable,
830 );
831 } else {
832 err.span_label(open_brace_span, "item list starts here")
833 .span_label(non_item_span, "non-item starts here")
834 .span_label(self.prev_token.span, "item list ends here");
835 }
836 if is_unnecessary_semicolon {
837 err.span_suggestion(
838 semicolon_span,
839 "consider removing this semicolon",
840 "",
841 Applicability::MaybeIncorrect,
842 );
843 }
844 err.emit();
845 break;
846 }
847 Ok(Some(item)) => items.extend(item),
848 Err(err) => {
849 self.consume_block(exp!(OpenBrace), exp!(CloseBrace), ConsumeClosingDelim::Yes);
850 err.with_span_label(
851 open_brace_span,
852 "while parsing this item list starting here",
853 )
854 .with_span_label(self.prev_token.span, "the item list ends here")
855 .emit();
856 break;
857 }
858 }
859 }
860 Ok(items)
861 }
862
863 fn recover_doc_comment_before_brace(&mut self) -> bool {
865 if let token::DocComment(..) = self.token.kind {
866 if self.look_ahead(1, |tok| tok == &token::CloseBrace) {
867 struct_span_code_err!(
869 self.dcx(),
870 self.token.span,
871 E0584,
872 "found a documentation comment that doesn't document anything",
873 )
874 .with_span_label(self.token.span, "this doc comment doesn't document anything")
875 .with_help(
876 "doc comments must come before what they document, if a comment was \
877 intended use `//`",
878 )
879 .emit();
880 self.bump();
881 return true;
882 }
883 }
884 false
885 }
886
887 fn parse_defaultness(&mut self) -> Defaultness {
889 if self.check_keyword(exp!(Default))
893 && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
894 {
895 self.bump(); Defaultness::Default(self.prev_token_uninterpolated_span())
897 } else {
898 Defaultness::Final
899 }
900 }
901
902 fn check_trait_front_matter(&mut self) -> bool {
904 self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait])
906 || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
908 || 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]))
909 || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Trait, kw::Auto]))
910 }
911
912 fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
914 let constness = self.parse_constness(Case::Sensitive);
915 if let Const::Yes(span) = constness {
916 self.psess.gated_spans.gate(sym::const_trait_impl, span);
917 }
918 let safety = self.parse_safety(Case::Sensitive);
919 let is_auto = if self.eat_keyword(exp!(Auto)) {
921 self.psess.gated_spans.gate(sym::auto_traits, self.prev_token.span);
922 IsAuto::Yes
923 } else {
924 IsAuto::No
925 };
926
927 self.expect_keyword(exp!(Trait))?;
928 let ident = self.parse_ident()?;
929 let mut generics = self.parse_generics()?;
930
931 let had_colon = self.eat(exp!(Colon));
933 let span_at_colon = self.prev_token.span;
934 let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
935
936 let span_before_eq = self.prev_token.span;
937 if self.eat(exp!(Eq)) {
938 if had_colon {
940 let span = span_at_colon.to(span_before_eq);
941 self.dcx().emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
942 }
943
944 let bounds = self.parse_generic_bounds()?;
945 generics.where_clause = self.parse_where_clause()?;
946 self.expect_semi()?;
947
948 let whole_span = lo.to(self.prev_token.span);
949 if is_auto == IsAuto::Yes {
950 self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
951 }
952 if let Safety::Unsafe(_) = safety {
953 self.dcx().emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span });
954 }
955
956 self.psess.gated_spans.gate(sym::trait_alias, whole_span);
957
958 Ok(ItemKind::TraitAlias(Box::new(TraitAlias { constness, ident, generics, bounds })))
959 } else {
960 generics.where_clause = self.parse_where_clause()?;
962 let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
963 Ok(ItemKind::Trait(Box::new(Trait {
964 constness,
965 is_auto,
966 safety,
967 ident,
968 generics,
969 bounds,
970 items,
971 })))
972 }
973 }
974
975 pub fn parse_impl_item(
976 &mut self,
977 force_collect: ForceCollect,
978 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
979 let fn_parse_mode =
980 FnParseMode { req_name: |_, _| true, context: FnContext::Impl, req_body: true };
981 self.parse_assoc_item(fn_parse_mode, force_collect)
982 }
983
984 pub fn parse_trait_item(
985 &mut self,
986 force_collect: ForceCollect,
987 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
988 let fn_parse_mode = FnParseMode {
989 req_name: |edition, _| edition >= Edition::Edition2018,
990 context: FnContext::Trait,
991 req_body: false,
992 };
993 self.parse_assoc_item(fn_parse_mode, force_collect)
994 }
995
996 fn parse_assoc_item(
998 &mut self,
999 fn_parse_mode: FnParseMode,
1000 force_collect: ForceCollect,
1001 ) -> PResult<'a, Option<Option<Box<AssocItem>>>> {
1002 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
1003 |Item { attrs, id, span, vis, kind, tokens }| {
1004 let kind = match AssocItemKind::try_from(kind) {
1005 Ok(kind) => kind,
1006 Err(kind) => match kind {
1007 ItemKind::Static(box StaticItem {
1008 ident,
1009 ty,
1010 safety: _,
1011 mutability: _,
1012 expr,
1013 define_opaque,
1014 }) => {
1015 self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
1016 let rhs = expr.map(ConstItemRhs::Body);
1017 AssocItemKind::Const(Box::new(ConstItem {
1018 defaultness: Defaultness::Final,
1019 ident,
1020 generics: Generics::default(),
1021 ty,
1022 rhs,
1023 define_opaque,
1024 }))
1025 }
1026 _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
1027 },
1028 };
1029 Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1030 },
1031 ))
1032 }
1033
1034 fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
1040 let ident = self.parse_ident()?;
1041 let mut generics = self.parse_generics()?;
1042
1043 let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() };
1045 generics.where_clause = self.parse_where_clause()?;
1046
1047 let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None };
1048
1049 let after_where_clause = self.parse_where_clause()?;
1050
1051 self.expect_semi()?;
1052
1053 Ok(ItemKind::TyAlias(Box::new(TyAlias {
1054 defaultness,
1055 ident,
1056 generics,
1057 after_where_clause,
1058 bounds,
1059 ty,
1060 })))
1061 }
1062
1063 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
1073 let lo = self.token.span;
1074
1075 let mut prefix =
1076 ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo(), tokens: None };
1077 let kind =
1078 if self.check(exp!(OpenBrace)) || self.check(exp!(Star)) || self.is_import_coupler() {
1079 let mod_sep_ctxt = self.token.span.ctxt();
1081 if self.eat_path_sep() {
1082 prefix
1083 .segments
1084 .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
1085 }
1086
1087 self.parse_use_tree_glob_or_nested()?
1088 } else {
1089 prefix = self.parse_path(PathStyle::Mod)?;
1091
1092 if self.eat_path_sep() {
1093 self.parse_use_tree_glob_or_nested()?
1094 } else {
1095 while self.eat_noexpect(&token::Colon) {
1097 self.dcx()
1098 .emit_err(errors::SingleColonImportPath { span: self.prev_token.span });
1099
1100 self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?;
1102 prefix.span = lo.to(self.prev_token.span);
1103 }
1104
1105 UseTreeKind::Simple(self.parse_rename()?)
1106 }
1107 };
1108
1109 Ok(UseTree { prefix, kind, span: lo.to(self.prev_token.span) })
1110 }
1111
1112 fn parse_use_tree_glob_or_nested(&mut self) -> PResult<'a, UseTreeKind> {
1114 Ok(if self.eat(exp!(Star)) {
1115 UseTreeKind::Glob
1116 } else {
1117 let lo = self.token.span;
1118 UseTreeKind::Nested {
1119 items: self.parse_use_tree_list()?,
1120 span: lo.to(self.prev_token.span),
1121 }
1122 })
1123 }
1124
1125 fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> {
1131 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1132 p.recover_vcs_conflict_marker();
1133 Ok((p.parse_use_tree()?, DUMMY_NODE_ID))
1134 })
1135 .map(|(r, _)| r)
1136 }
1137
1138 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
1139 if self.eat_keyword(exp!(As)) {
1140 self.parse_ident_or_underscore().map(Some)
1141 } else {
1142 Ok(None)
1143 }
1144 }
1145
1146 fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
1147 match self.token.ident() {
1148 Some((ident @ Ident { name: kw::Underscore, .. }, IdentIsRaw::No)) => {
1149 self.bump();
1150 Ok(ident)
1151 }
1152 _ => self.parse_ident(),
1153 }
1154 }
1155
1156 fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemKind> {
1165 let orig_ident = self.parse_crate_name_with_dashes()?;
1167 let (orig_name, item_ident) = if let Some(rename) = self.parse_rename()? {
1168 (Some(orig_ident.name), rename)
1169 } else {
1170 (None, orig_ident)
1171 };
1172 self.expect_semi()?;
1173 Ok(ItemKind::ExternCrate(orig_name, item_ident))
1174 }
1175
1176 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
1177 let ident = if self.token.is_keyword(kw::SelfLower) {
1178 self.parse_path_segment_ident()
1179 } else {
1180 self.parse_ident()
1181 }?;
1182
1183 let dash = exp!(Minus);
1184 if self.token != dash.tok {
1185 return Ok(ident);
1186 }
1187
1188 let mut dashes = vec![];
1190 let mut idents = vec![];
1191 while self.eat(dash) {
1192 dashes.push(self.prev_token.span);
1193 idents.push(self.parse_ident()?);
1194 }
1195
1196 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
1197 let mut fixed_name = ident.name.to_string();
1198 for part in idents {
1199 write!(fixed_name, "_{}", part.name).unwrap();
1200 }
1201
1202 self.dcx().emit_err(errors::ExternCrateNameWithDashes {
1203 span: fixed_name_sp,
1204 sugg: errors::ExternCrateNameWithDashesSugg { dashes },
1205 });
1206
1207 Ok(Ident::from_str_and_span(&fixed_name, fixed_name_sp))
1208 }
1209
1210 fn parse_item_foreign_mod(
1221 &mut self,
1222 attrs: &mut AttrVec,
1223 mut safety: Safety,
1224 ) -> PResult<'a, ItemKind> {
1225 let extern_span = self.prev_token_uninterpolated_span();
1226 let abi = self.parse_abi(); if safety == Safety::Default
1229 && self.token.is_keyword(kw::Unsafe)
1230 && self.look_ahead(1, |t| *t == token::OpenBrace)
1231 {
1232 self.expect(exp!(OpenBrace)).unwrap_err().emit();
1233 safety = Safety::Unsafe(self.token.span);
1234 let _ = self.eat_keyword(exp!(Unsafe));
1235 }
1236 Ok(ItemKind::ForeignMod(ast::ForeignMod {
1237 extern_span,
1238 safety,
1239 abi,
1240 items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
1241 }))
1242 }
1243
1244 pub fn parse_foreign_item(
1246 &mut self,
1247 force_collect: ForceCollect,
1248 ) -> PResult<'a, Option<Option<Box<ForeignItem>>>> {
1249 let fn_parse_mode = FnParseMode {
1250 req_name: |_, is_dot_dot_dot| is_dot_dot_dot == IsDotDotDot::No,
1251 context: FnContext::Free,
1252 req_body: false,
1253 };
1254 Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
1255 |Item { attrs, id, span, vis, kind, tokens }| {
1256 let kind = match ForeignItemKind::try_from(kind) {
1257 Ok(kind) => kind,
1258 Err(kind) => match kind {
1259 ItemKind::Const(box ConstItem { ident, ty, rhs, .. }) => {
1260 let const_span = Some(span.with_hi(ident.span.lo()))
1261 .filter(|span| span.can_be_used_for_suggestions());
1262 self.dcx().emit_err(errors::ExternItemCannotBeConst {
1263 ident_span: ident.span,
1264 const_span,
1265 });
1266 ForeignItemKind::Static(Box::new(StaticItem {
1267 ident,
1268 ty,
1269 mutability: Mutability::Not,
1270 expr: rhs.map(|b| match b {
1271 ConstItemRhs::TypeConst(anon_const) => anon_const.value,
1272 ConstItemRhs::Body(expr) => expr,
1273 }),
1274 safety: Safety::Default,
1275 define_opaque: None,
1276 }))
1277 }
1278 _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
1279 },
1280 };
1281 Some(Box::new(Item { attrs, id, span, vis, kind, tokens }))
1282 },
1283 ))
1284 }
1285
1286 fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
1287 let span = self.psess.source_map().guess_head_span(span);
1289 let descr = kind.descr();
1290 let help = match kind {
1291 ItemKind::DelegationMac(deleg) if deleg.suffixes.is_none() => false,
1292 _ => true,
1293 };
1294 self.dcx().emit_err(errors::BadItemKind { span, descr, ctx, help });
1295 None
1296 }
1297
1298 fn is_use_closure(&self) -> bool {
1299 if self.token.is_keyword(kw::Use) {
1300 self.look_ahead(1, |token| {
1302 let dist =
1304 if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 };
1305
1306 self.look_ahead(dist, |token| matches!(token.kind, token::Or | token::OrOr))
1307 })
1308 } else {
1309 false
1310 }
1311 }
1312
1313 fn is_unsafe_foreign_mod(&self) -> bool {
1314 if !self.token.is_keyword(kw::Unsafe) {
1316 return false;
1317 }
1318 if !self.is_keyword_ahead(1, &[kw::Extern]) {
1320 return false;
1321 }
1322
1323 let n = if self.look_ahead(2, |t| t.can_begin_string_literal()) { 3 } else { 2 };
1325
1326 self.tree_look_ahead(n, |t| matches!(t, TokenTree::Delimited(_, _, Delimiter::Brace, _)))
1331 == Some(true)
1332 }
1333
1334 fn is_static_global(&mut self) -> bool {
1335 if self.check_keyword(exp!(Static)) {
1336 !self.look_ahead(1, |token| {
1338 if token.is_keyword(kw::Move) || token.is_keyword(kw::Use) {
1339 return true;
1340 }
1341 matches!(token.kind, token::Or | token::OrOr)
1342 })
1343 } else {
1344 (self.check_keyword(exp!(Unsafe)) || self.check_keyword(exp!(Safe)))
1346 && self.look_ahead(1, |t| t.is_keyword(kw::Static))
1347 }
1348 }
1349
1350 fn recover_const_mut(&mut self, const_span: Span) {
1352 if self.eat_keyword(exp!(Mut)) {
1353 let span = self.prev_token.span;
1354 self.dcx()
1355 .emit_err(errors::ConstGlobalCannotBeMutable { ident_span: span, const_span });
1356 } else if self.eat_keyword(exp!(Let)) {
1357 let span = self.prev_token.span;
1358 self.dcx().emit_err(errors::ConstLetMutuallyExclusive { span: const_span.to(span) });
1359 }
1360 }
1361
1362 fn recover_const_impl(
1364 &mut self,
1365 const_span: Span,
1366 attrs: &mut AttrVec,
1367 defaultness: Defaultness,
1368 ) -> PResult<'a, ItemKind> {
1369 let impl_span = self.token.span;
1370 let err = self.expected_ident_found_err();
1371
1372 let mut item_kind = match self.parse_item_impl(attrs, defaultness) {
1374 Ok(item_kind) => item_kind,
1375 Err(recovery_error) => {
1376 recovery_error.cancel();
1378 return Err(err);
1379 }
1380 };
1381
1382 match &mut item_kind {
1383 ItemKind::Impl(Impl { of_trait: Some(of_trait), .. }) => {
1384 of_trait.constness = Const::Yes(const_span);
1385
1386 let before_trait = of_trait.trait_ref.path.span.shrink_to_lo();
1387 let const_up_to_impl = const_span.with_hi(impl_span.lo());
1388 err.with_multipart_suggestion(
1389 "you might have meant to write a const trait impl",
1390 vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())],
1391 Applicability::MaybeIncorrect,
1392 )
1393 .emit();
1394 }
1395 ItemKind::Impl { .. } => return Err(err),
1396 _ => unreachable!(),
1397 }
1398
1399 Ok(item_kind)
1400 }
1401
1402 fn parse_static_item(
1409 &mut self,
1410 safety: Safety,
1411 mutability: Mutability,
1412 ) -> PResult<'a, ItemKind> {
1413 let ident = self.parse_ident()?;
1414
1415 if self.token == TokenKind::Lt && self.may_recover() {
1416 let generics = self.parse_generics()?;
1417 self.dcx().emit_err(errors::StaticWithGenerics { span: generics.span });
1418 }
1419
1420 let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
1423 (true, false) => self.parse_ty()?,
1424 (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
1427 };
1428
1429 let expr = if self.eat(exp!(Eq)) { Some(self.parse_expr()?) } else { None };
1430
1431 self.expect_semi()?;
1432
1433 let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
1434 Ok(ItemKind::Static(Box::new(item)))
1435 }
1436
1437 fn parse_const_item(
1443 &mut self,
1444 attrs: &[Attribute],
1445 ) -> PResult<'a, (Ident, Generics, Box<Ty>, Option<ast::ConstItemRhs>)> {
1446 let ident = self.parse_ident_or_underscore()?;
1447
1448 let mut generics = self.parse_generics()?;
1449
1450 if !generics.span.is_empty() {
1453 self.psess.gated_spans.gate(sym::generic_const_items, generics.span);
1454 }
1455
1456 let ty = match (
1459 self.eat(exp!(Colon)),
1460 self.check(exp!(Eq)) | self.check(exp!(Semi)) | self.check_keyword(exp!(Where)),
1461 ) {
1462 (true, false) => self.parse_ty()?,
1463 (colon, _) => self.recover_missing_global_item_type(colon, None),
1465 };
1466
1467 let before_where_clause =
1470 if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() };
1471
1472 let rhs = if self.eat(exp!(Eq)) {
1473 if attr::contains_name(attrs, sym::type_const) {
1474 Some(ConstItemRhs::TypeConst(self.parse_expr_anon_const()?))
1475 } else {
1476 Some(ConstItemRhs::Body(self.parse_expr()?))
1477 }
1478 } else {
1479 None
1480 };
1481
1482 let after_where_clause = self.parse_where_clause()?;
1483
1484 if before_where_clause.has_where_token
1488 && let Some(rhs) = &rhs
1489 {
1490 self.dcx().emit_err(errors::WhereClauseBeforeConstBody {
1491 span: before_where_clause.span,
1492 name: ident.span,
1493 body: rhs.span(),
1494 sugg: if !after_where_clause.has_where_token {
1495 self.psess.source_map().span_to_snippet(rhs.span()).ok().map(|body_s| {
1496 errors::WhereClauseBeforeConstBodySugg {
1497 left: before_where_clause.span.shrink_to_lo(),
1498 snippet: body_s,
1499 right: before_where_clause.span.shrink_to_hi().to(rhs.span()),
1500 }
1501 })
1502 } else {
1503 None
1506 },
1507 });
1508 }
1509
1510 let mut predicates = before_where_clause.predicates;
1517 predicates.extend(after_where_clause.predicates);
1518 let where_clause = WhereClause {
1519 has_where_token: before_where_clause.has_where_token
1520 || after_where_clause.has_where_token,
1521 predicates,
1522 span: if after_where_clause.has_where_token {
1523 after_where_clause.span
1524 } else {
1525 before_where_clause.span
1526 },
1527 };
1528
1529 if where_clause.has_where_token {
1530 self.psess.gated_spans.gate(sym::generic_const_items, where_clause.span);
1531 }
1532
1533 generics.where_clause = where_clause;
1534
1535 self.expect_semi()?;
1536
1537 Ok((ident, generics, ty, rhs))
1538 }
1539
1540 fn recover_missing_global_item_type(
1543 &mut self,
1544 colon_present: bool,
1545 m: Option<Mutability>,
1546 ) -> Box<Ty> {
1547 let kind = match m {
1550 Some(Mutability::Mut) => "static mut",
1551 Some(Mutability::Not) => "static",
1552 None => "const",
1553 };
1554
1555 let colon = match colon_present {
1556 true => "",
1557 false => ":",
1558 };
1559
1560 let span = self.prev_token.span.shrink_to_hi();
1561 let err = self.dcx().create_err(errors::MissingConstType { span, colon, kind });
1562 err.stash(span, StashKey::ItemNoType);
1563
1564 Box::new(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
1567 }
1568
1569 fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
1571 if self.token.is_keyword(kw::Struct) {
1572 let span = self.prev_token.span.to(self.token.span);
1573 let err = errors::EnumStructMutuallyExclusive { span };
1574 if self.look_ahead(1, |t| t.is_ident()) {
1575 self.bump();
1576 self.dcx().emit_err(err);
1577 } else {
1578 return Err(self.dcx().create_err(err));
1579 }
1580 }
1581
1582 let prev_span = self.prev_token.span;
1583 let ident = self.parse_ident()?;
1584 let mut generics = self.parse_generics()?;
1585 generics.where_clause = self.parse_where_clause()?;
1586
1587 let (variants, _) = if self.token == TokenKind::Semi {
1589 self.dcx().emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
1590 self.bump();
1591 (thin_vec![], Trailing::No)
1592 } else {
1593 self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
1594 p.parse_enum_variant(ident.span)
1595 })
1596 .map_err(|mut err| {
1597 err.span_label(ident.span, "while parsing this enum");
1598 if self.prev_token.is_non_reserved_ident() && self.token == token::Colon {
1600 let snapshot = self.create_snapshot_for_diagnostic();
1601 self.bump();
1602 match self.parse_ty() {
1603 Ok(_) => {
1604 err.span_suggestion_verbose(
1605 prev_span,
1606 "perhaps you meant to use `struct` here",
1607 "struct",
1608 Applicability::MaybeIncorrect,
1609 );
1610 }
1611 Err(e) => {
1612 e.cancel();
1613 }
1614 }
1615 self.restore_snapshot(snapshot);
1616 }
1617 self.eat_to_tokens(&[exp!(CloseBrace)]);
1618 self.bump(); err
1620 })?
1621 };
1622
1623 let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
1624 Ok(ItemKind::Enum(ident, generics, enum_definition))
1625 }
1626
1627 fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
1628 self.recover_vcs_conflict_marker();
1629 let variant_attrs = self.parse_outer_attributes()?;
1630 self.recover_vcs_conflict_marker();
1631 let help = "enum variants can be `Variant`, `Variant = <integer>`, \
1632 `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`";
1633 self.collect_tokens(None, variant_attrs, ForceCollect::No, |this, variant_attrs| {
1634 let vlo = this.token.span;
1635
1636 let vis = this.parse_visibility(FollowedByType::No)?;
1637 if !this.recover_nested_adt_item(kw::Enum)? {
1638 return Ok((None, Trailing::No, UsePreAttrPos::No));
1639 }
1640 let ident = this.parse_field_ident("enum", vlo)?;
1641
1642 if this.token == token::Bang {
1643 if let Err(err) = this.unexpected() {
1644 err.with_note(fluent::parse_macro_expands_to_enum_variant).emit();
1645 }
1646
1647 this.bump();
1648 this.parse_delim_args()?;
1649
1650 return Ok((None, Trailing::from(this.token == token::Comma), UsePreAttrPos::No));
1651 }
1652
1653 let struct_def = if this.check(exp!(OpenBrace)) {
1654 let (fields, recovered) =
1656 match this.parse_record_struct_body("struct", ident.span, false) {
1657 Ok((fields, recovered)) => (fields, recovered),
1658 Err(mut err) => {
1659 if this.token == token::Colon {
1660 return Err(err);
1662 }
1663 this.eat_to_tokens(&[exp!(CloseBrace)]);
1664 this.bump(); err.span_label(span, "while parsing this enum");
1666 err.help(help);
1667 let guar = err.emit();
1668 (thin_vec![], Recovered::Yes(guar))
1669 }
1670 };
1671 VariantData::Struct { fields, recovered }
1672 } else if this.check(exp!(OpenParen)) {
1673 let body = match this.parse_tuple_struct_body() {
1674 Ok(body) => body,
1675 Err(mut err) => {
1676 if this.token == token::Colon {
1677 return Err(err);
1679 }
1680 this.eat_to_tokens(&[exp!(CloseParen)]);
1681 this.bump(); err.span_label(span, "while parsing this enum");
1683 err.help(help);
1684 err.emit();
1685 thin_vec![]
1686 }
1687 };
1688 VariantData::Tuple(body, DUMMY_NODE_ID)
1689 } else {
1690 VariantData::Unit(DUMMY_NODE_ID)
1691 };
1692
1693 let disr_expr =
1694 if this.eat(exp!(Eq)) { Some(this.parse_expr_anon_const()?) } else { None };
1695
1696 let vr = ast::Variant {
1697 ident,
1698 vis,
1699 id: DUMMY_NODE_ID,
1700 attrs: variant_attrs,
1701 data: struct_def,
1702 disr_expr,
1703 span: vlo.to(this.prev_token.span),
1704 is_placeholder: false,
1705 };
1706
1707 Ok((Some(vr), Trailing::from(this.token == token::Comma), UsePreAttrPos::No))
1708 })
1709 .map_err(|mut err| {
1710 err.help(help);
1711 err
1712 })
1713 }
1714
1715 fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
1717 let ident = self.parse_ident()?;
1718
1719 let mut generics = self.parse_generics()?;
1720
1721 let vdata = if self.token.is_keyword(kw::Where) {
1736 let tuple_struct_body;
1737 (generics.where_clause, tuple_struct_body) =
1738 self.parse_struct_where_clause(ident, generics.span)?;
1739
1740 if let Some(body) = tuple_struct_body {
1741 let body = VariantData::Tuple(body, DUMMY_NODE_ID);
1743 self.expect_semi()?;
1744 body
1745 } else if self.eat(exp!(Semi)) {
1746 VariantData::Unit(DUMMY_NODE_ID)
1748 } else {
1749 let (fields, recovered) = self.parse_record_struct_body(
1751 "struct",
1752 ident.span,
1753 generics.where_clause.has_where_token,
1754 )?;
1755 VariantData::Struct { fields, recovered }
1756 }
1757 } else if self.eat(exp!(Semi)) {
1759 VariantData::Unit(DUMMY_NODE_ID)
1760 } else if self.token == token::OpenBrace {
1762 let (fields, recovered) = self.parse_record_struct_body(
1763 "struct",
1764 ident.span,
1765 generics.where_clause.has_where_token,
1766 )?;
1767 VariantData::Struct { fields, recovered }
1768 } else if self.token == token::OpenParen {
1770 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1771 generics.where_clause = self.parse_where_clause()?;
1772 self.expect_semi()?;
1773 body
1774 } else {
1775 let err = errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token);
1776 return Err(self.dcx().create_err(err));
1777 };
1778
1779 Ok(ItemKind::Struct(ident, generics, vdata))
1780 }
1781
1782 fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
1784 let ident = self.parse_ident()?;
1785
1786 let mut generics = self.parse_generics()?;
1787
1788 let vdata = if self.token.is_keyword(kw::Where) {
1789 generics.where_clause = self.parse_where_clause()?;
1790 let (fields, recovered) = self.parse_record_struct_body(
1791 "union",
1792 ident.span,
1793 generics.where_clause.has_where_token,
1794 )?;
1795 VariantData::Struct { fields, recovered }
1796 } else if self.token == token::OpenBrace {
1797 let (fields, recovered) = self.parse_record_struct_body(
1798 "union",
1799 ident.span,
1800 generics.where_clause.has_where_token,
1801 )?;
1802 VariantData::Struct { fields, recovered }
1803 } else {
1804 let token_str = super::token_descr(&self.token);
1805 let msg = format!("expected `where` or `{{` after union name, found {token_str}");
1806 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1807 err.span_label(self.token.span, "expected `where` or `{` after union name");
1808 return Err(err);
1809 };
1810
1811 Ok(ItemKind::Union(ident, generics, vdata))
1812 }
1813
1814 pub(crate) fn parse_record_struct_body(
1819 &mut self,
1820 adt_ty: &str,
1821 ident_span: Span,
1822 parsed_where: bool,
1823 ) -> PResult<'a, (ThinVec<FieldDef>, Recovered)> {
1824 let mut fields = ThinVec::new();
1825 let mut recovered = Recovered::No;
1826 if self.eat(exp!(OpenBrace)) {
1827 while self.token != token::CloseBrace {
1828 match self.parse_field_def(adt_ty, ident_span) {
1829 Ok(field) => {
1830 fields.push(field);
1831 }
1832 Err(mut err) => {
1833 self.consume_block(
1834 exp!(OpenBrace),
1835 exp!(CloseBrace),
1836 ConsumeClosingDelim::No,
1837 );
1838 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1839 let guar = err.emit();
1840 recovered = Recovered::Yes(guar);
1841 break;
1842 }
1843 }
1844 }
1845 self.expect(exp!(CloseBrace))?;
1846 } else {
1847 let token_str = super::token_descr(&self.token);
1848 let where_str = if parsed_where { "" } else { "`where`, or " };
1849 let msg = format!("expected {where_str}`{{` after struct name, found {token_str}");
1850 let mut err = self.dcx().struct_span_err(self.token.span, msg);
1851 err.span_label(self.token.span, format!("expected {where_str}`{{` after struct name",));
1852 return Err(err);
1853 }
1854
1855 Ok((fields, recovered))
1856 }
1857
1858 fn parse_unsafe_field(&mut self) -> Safety {
1859 if self.eat_keyword(exp!(Unsafe)) {
1861 let span = self.prev_token.span;
1862 self.psess.gated_spans.gate(sym::unsafe_fields, span);
1863 Safety::Unsafe(span)
1864 } else {
1865 Safety::Default
1866 }
1867 }
1868
1869 pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
1870 self.parse_paren_comma_seq(|p| {
1873 let attrs = p.parse_outer_attributes()?;
1874 p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
1875 let mut snapshot = None;
1876 if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
1877 snapshot = Some(p.create_snapshot_for_diagnostic());
1881 }
1882 let lo = p.token.span;
1883 let vis = match p.parse_visibility(FollowedByType::Yes) {
1884 Ok(vis) => vis,
1885 Err(err) => {
1886 if let Some(ref mut snapshot) = snapshot {
1887 snapshot.recover_vcs_conflict_marker();
1888 }
1889 return Err(err);
1890 }
1891 };
1892 let ty = match p.parse_ty() {
1895 Ok(ty) => ty,
1896 Err(err) => {
1897 if let Some(ref mut snapshot) = snapshot {
1898 snapshot.recover_vcs_conflict_marker();
1899 }
1900 return Err(err);
1901 }
1902 };
1903 let mut default = None;
1904 if p.token == token::Eq {
1905 let mut snapshot = p.create_snapshot_for_diagnostic();
1906 snapshot.bump();
1907 match snapshot.parse_expr_anon_const() {
1908 Ok(const_expr) => {
1909 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
1910 p.psess.gated_spans.gate(sym::default_field_values, sp);
1911 p.restore_snapshot(snapshot);
1912 default = Some(const_expr);
1913 }
1914 Err(err) => {
1915 err.cancel();
1916 }
1917 }
1918 }
1919
1920 Ok((
1921 FieldDef {
1922 span: lo.to(ty.span),
1923 vis,
1924 safety: Safety::Default,
1925 ident: None,
1926 id: DUMMY_NODE_ID,
1927 ty,
1928 default,
1929 attrs,
1930 is_placeholder: false,
1931 },
1932 Trailing::from(p.token == token::Comma),
1933 UsePreAttrPos::No,
1934 ))
1935 })
1936 })
1937 .map(|(r, _)| r)
1938 }
1939
1940 fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
1942 self.recover_vcs_conflict_marker();
1943 let attrs = self.parse_outer_attributes()?;
1944 self.recover_vcs_conflict_marker();
1945 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
1946 let lo = this.token.span;
1947 let vis = this.parse_visibility(FollowedByType::No)?;
1948 let safety = this.parse_unsafe_field();
1949 this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
1950 .map(|field| (field, Trailing::No, UsePreAttrPos::No))
1951 })
1952 }
1953
1954 fn parse_single_struct_field(
1956 &mut self,
1957 adt_ty: &str,
1958 lo: Span,
1959 vis: Visibility,
1960 safety: Safety,
1961 attrs: AttrVec,
1962 ident_span: Span,
1963 ) -> PResult<'a, FieldDef> {
1964 let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
1965 match self.token.kind {
1966 token::Comma => {
1967 self.bump();
1968 }
1969 token::Semi => {
1970 self.bump();
1971 let sp = self.prev_token.span;
1972 let mut err =
1973 self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
1974 err.span_suggestion_short(
1975 sp,
1976 "replace `;` with `,`",
1977 ",",
1978 Applicability::MachineApplicable,
1979 );
1980 err.span_label(ident_span, format!("while parsing this {adt_ty}"));
1981 err.emit();
1982 }
1983 token::CloseBrace => {}
1984 token::DocComment(..) => {
1985 let previous_span = self.prev_token.span;
1986 let mut err = errors::DocCommentDoesNotDocumentAnything {
1987 span: self.token.span,
1988 missing_comma: None,
1989 };
1990 self.bump(); if self.eat(exp!(Comma)) || self.token == token::CloseBrace {
1992 self.dcx().emit_err(err);
1993 } else {
1994 let sp = previous_span.shrink_to_hi();
1995 err.missing_comma = Some(sp);
1996 return Err(self.dcx().create_err(err));
1997 }
1998 }
1999 _ => {
2000 let sp = self.prev_token.span.shrink_to_hi();
2001 let msg =
2002 format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
2003
2004 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
2006 && let Some(last_segment) = segments.last()
2007 {
2008 let guar = self.check_trailing_angle_brackets(
2009 last_segment,
2010 &[exp!(Comma), exp!(CloseBrace)],
2011 );
2012 if let Some(_guar) = guar {
2013 let _ = self.eat(exp!(Comma));
2016
2017 return Ok(a_var);
2020 }
2021 }
2022
2023 let mut err = self.dcx().struct_span_err(sp, msg);
2024
2025 if self.token.is_ident()
2026 || (self.token == TokenKind::Pound
2027 && (self.look_ahead(1, |t| t == &token::OpenBracket)))
2028 {
2029 err.span_suggestion(
2032 sp,
2033 "try adding a comma",
2034 ",",
2035 Applicability::MachineApplicable,
2036 );
2037 err.emit();
2038 } else {
2039 return Err(err);
2040 }
2041 }
2042 }
2043 Ok(a_var)
2044 }
2045
2046 fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
2047 if let Err(err) = self.expect(exp!(Colon)) {
2048 let sm = self.psess.source_map();
2049 let eq_typo = self.token == token::Eq && self.look_ahead(1, |t| t.is_path_start());
2050 let semi_typo = self.token == token::Semi
2051 && self.look_ahead(1, |t| {
2052 t.is_path_start()
2053 && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
2056 (Ok(l), Ok(r)) => l.line == r.line,
2057 _ => true,
2058 }
2059 });
2060 if eq_typo || semi_typo {
2061 self.bump();
2062 err.with_span_suggestion_short(
2064 self.prev_token.span,
2065 "field names and their types are separated with `:`",
2066 ":",
2067 Applicability::MachineApplicable,
2068 )
2069 .emit();
2070 } else {
2071 return Err(err);
2072 }
2073 }
2074 Ok(())
2075 }
2076
2077 fn parse_name_and_ty(
2079 &mut self,
2080 adt_ty: &str,
2081 lo: Span,
2082 vis: Visibility,
2083 safety: Safety,
2084 attrs: AttrVec,
2085 ) -> PResult<'a, FieldDef> {
2086 let name = self.parse_field_ident(adt_ty, lo)?;
2087 if self.token == token::Bang {
2088 if let Err(mut err) = self.unexpected() {
2089 err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
2091 return Err(err);
2092 }
2093 }
2094 self.expect_field_ty_separator()?;
2095 let ty = self.parse_ty()?;
2096 if self.token == token::Colon && self.look_ahead(1, |&t| t != token::Colon) {
2097 self.dcx()
2098 .struct_span_err(self.token.span, "found single colon in a struct field type path")
2099 .with_span_suggestion_verbose(
2100 self.token.span,
2101 "write a path separator here",
2102 "::",
2103 Applicability::MaybeIncorrect,
2104 )
2105 .emit();
2106 }
2107 let default = if self.token == token::Eq {
2108 self.bump();
2109 let const_expr = self.parse_expr_anon_const()?;
2110 let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
2111 self.psess.gated_spans.gate(sym::default_field_values, sp);
2112 Some(const_expr)
2113 } else {
2114 None
2115 };
2116 Ok(FieldDef {
2117 span: lo.to(self.prev_token.span),
2118 ident: Some(name),
2119 vis,
2120 safety,
2121 id: DUMMY_NODE_ID,
2122 ty,
2123 default,
2124 attrs,
2125 is_placeholder: false,
2126 })
2127 }
2128
2129 fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
2132 let (ident, is_raw) = self.ident_or_err(true)?;
2133 if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
2134 let snapshot = self.create_snapshot_for_diagnostic();
2135 let err = if self.check_fn_front_matter(false, Case::Sensitive) {
2136 let inherited_vis =
2137 Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None };
2138 let fn_parse_mode =
2140 FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true };
2141 match self.parse_fn(
2142 &mut AttrVec::new(),
2143 fn_parse_mode,
2144 lo,
2145 &inherited_vis,
2146 Case::Insensitive,
2147 ) {
2148 Ok(_) => {
2149 self.dcx().struct_span_err(
2150 lo.to(self.prev_token.span),
2151 format!("functions are not allowed in {adt_ty} definitions"),
2152 )
2153 .with_help(
2154 "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
2155 )
2156 .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information")
2157 }
2158 Err(err) => {
2159 err.cancel();
2160 self.restore_snapshot(snapshot);
2161 self.expected_ident_found_err()
2162 }
2163 }
2164 } else if self.eat_keyword(exp!(Struct)) {
2165 match self.parse_item_struct() {
2166 Ok(item) => {
2167 let ItemKind::Struct(ident, ..) = item else { unreachable!() };
2168 self.dcx()
2169 .struct_span_err(
2170 lo.with_hi(ident.span.hi()),
2171 format!("structs are not allowed in {adt_ty} definitions"),
2172 )
2173 .with_help(
2174 "consider creating a new `struct` definition instead of nesting",
2175 )
2176 }
2177 Err(err) => {
2178 err.cancel();
2179 self.restore_snapshot(snapshot);
2180 self.expected_ident_found_err()
2181 }
2182 }
2183 } else {
2184 let mut err = self.expected_ident_found_err();
2185 if self.eat_keyword_noexpect(kw::Let)
2186 && let removal_span = self.prev_token.span.until(self.token.span)
2187 && let Ok(ident) = self
2188 .parse_ident_common(false)
2189 .map_err(|err| err.cancel())
2191 && self.token == TokenKind::Colon
2192 {
2193 err.span_suggestion(
2194 removal_span,
2195 "remove this `let` keyword",
2196 String::new(),
2197 Applicability::MachineApplicable,
2198 );
2199 err.note("the `let` keyword is not allowed in `struct` fields");
2200 err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information");
2201 err.emit();
2202 return Ok(ident);
2203 } else {
2204 self.restore_snapshot(snapshot);
2205 }
2206 err
2207 };
2208 return Err(err);
2209 }
2210 self.bump();
2211 Ok(ident)
2212 }
2213
2214 fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
2222 let ident = self.parse_ident()?;
2223 let body = if self.check(exp!(OpenBrace)) {
2224 self.parse_delim_args()? } else if self.check(exp!(OpenParen)) {
2226 let params = self.parse_token_tree(); let pspan = params.span();
2228 if !self.check(exp!(OpenBrace)) {
2229 self.unexpected()?;
2230 }
2231 let body = self.parse_token_tree(); let bspan = body.span();
2234 let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); let tokens = TokenStream::new(vec![params, arrow, body]);
2236 let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2237 Box::new(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2238 } else {
2239 self.unexpected_any()?
2240 };
2241
2242 self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
2243 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false }))
2244 }
2245
2246 fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2248 if self.check_keyword(exp!(MacroRules)) {
2249 let macro_rules_span = self.token.span;
2250
2251 if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
2252 return IsMacroRulesItem::Yes { has_bang: true };
2253 } else if self.look_ahead(1, |t| t.is_ident()) {
2254 self.dcx().emit_err(errors::MacroRulesMissingBang {
2256 span: macro_rules_span,
2257 hi: macro_rules_span.shrink_to_hi(),
2258 });
2259
2260 return IsMacroRulesItem::Yes { has_bang: false };
2261 }
2262 }
2263
2264 IsMacroRulesItem::No
2265 }
2266
2267 fn parse_item_macro_rules(
2269 &mut self,
2270 vis: &Visibility,
2271 has_bang: bool,
2272 ) -> PResult<'a, ItemKind> {
2273 self.expect_keyword(exp!(MacroRules))?; if has_bang {
2276 self.expect(exp!(Bang))?; }
2278 let ident = self.parse_ident()?;
2279
2280 if self.eat(exp!(Bang)) {
2281 let span = self.prev_token.span;
2283 self.dcx().emit_err(errors::MacroNameRemoveBang { span });
2284 }
2285
2286 let body = self.parse_delim_args()?;
2287 self.eat_semi_for_macro_if_needed(&body);
2288 self.complain_if_pub_macro(vis, true);
2289
2290 Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true }))
2291 }
2292
2293 fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
2296 if let VisibilityKind::Inherited = vis.kind {
2297 return;
2298 }
2299
2300 let vstr = pprust::vis_to_string(vis);
2301 let vstr = vstr.trim_end();
2302 if macro_rules {
2303 self.dcx().emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
2304 } else {
2305 self.dcx().emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
2306 }
2307 }
2308
2309 fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) {
2310 if args.need_semicolon() && !self.eat(exp!(Semi)) {
2311 self.report_invalid_macro_expansion_item(args);
2312 }
2313 }
2314
2315 fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) {
2316 let span = args.dspan.entire();
2317 let mut err = self.dcx().struct_span_err(
2318 span,
2319 "macros that expand to items must be delimited with braces or followed by a semicolon",
2320 );
2321 if !span.from_expansion() {
2324 let DelimSpan { open, close } = args.dspan;
2325 err.multipart_suggestion(
2326 "change the delimiters to curly braces",
2327 vec![(open, "{".to_string()), (close, '}'.to_string())],
2328 Applicability::MaybeIncorrect,
2329 );
2330 err.span_suggestion(
2331 span.with_neighbor(self.token.span).shrink_to_hi(),
2332 "add a semicolon",
2333 ';',
2334 Applicability::MaybeIncorrect,
2335 );
2336 }
2337 err.emit();
2338 }
2339
2340 fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
2343 if (self.token.is_keyword(kw::Enum)
2344 || self.token.is_keyword(kw::Struct)
2345 || self.token.is_keyword(kw::Union))
2346 && self.look_ahead(1, |t| t.is_ident())
2347 {
2348 let kw_token = self.token;
2349 let kw_str = pprust::token_to_string(&kw_token);
2350 let item = self.parse_item(ForceCollect::No)?;
2351 let mut item = item.unwrap().span;
2352 if self.token == token::Comma {
2353 item = item.to(self.token.span);
2354 }
2355 self.dcx().emit_err(errors::NestedAdt {
2356 span: kw_token.span,
2357 item,
2358 kw_str,
2359 keyword: keyword.as_str(),
2360 });
2361 return Ok(false);
2363 }
2364 Ok(true)
2365 }
2366}
2367
2368type ReqName = fn(Edition, IsDotDotDot) -> bool;
2377
2378#[derive(Copy, Clone, PartialEq)]
2379pub(crate) enum IsDotDotDot {
2380 Yes,
2381 No,
2382}
2383
2384#[derive(Clone, Copy)]
2392pub(crate) struct FnParseMode {
2393 pub(super) req_name: ReqName,
2419 pub(super) context: FnContext,
2422 pub(super) req_body: bool,
2441}
2442
2443#[derive(Clone, Copy, PartialEq, Eq)]
2446pub(crate) enum FnContext {
2447 Free,
2449 Trait,
2451 Impl,
2453}
2454
2455impl<'a> Parser<'a> {
2457 fn parse_fn(
2459 &mut self,
2460 attrs: &mut AttrVec,
2461 fn_parse_mode: FnParseMode,
2462 sig_lo: Span,
2463 vis: &Visibility,
2464 case: Case,
2465 ) -> PResult<'a, (Ident, FnSig, Generics, Option<Box<FnContract>>, Option<Box<Block>>)> {
2466 let fn_span = self.token.span;
2467 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)
2471 {
2472 Ok(decl) => decl,
2473 Err(old_err) => {
2474 if self.token.is_keyword(kw::For) {
2476 old_err.cancel();
2477 return Err(self.dcx().create_err(errors::FnTypoWithImpl { fn_span }));
2478 } else {
2479 return Err(old_err);
2480 }
2481 }
2482 };
2483
2484 let fn_params_end = self.prev_token.span.shrink_to_hi();
2487
2488 let contract = self.parse_contract()?;
2489
2490 generics.where_clause = self.parse_where_clause()?; let fn_params_end =
2494 if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2495
2496 let mut sig_hi = self.prev_token.span;
2497 let body =
2499 self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
2500 let fn_sig_span = sig_lo.to(sig_hi);
2501 Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
2502 }
2503
2504 fn error_fn_body_not_found(
2506 &mut self,
2507 ident_span: Span,
2508 req_body: bool,
2509 fn_params_end: Option<Span>,
2510 ) -> PResult<'a, ErrorGuaranteed> {
2511 let expected: &[_] =
2512 if req_body { &[exp!(OpenBrace)] } else { &[exp!(Semi), exp!(OpenBrace)] };
2513 match self.expected_one_of_not_found(&[], expected) {
2514 Ok(error_guaranteed) => Ok(error_guaranteed),
2515 Err(mut err) => {
2516 if self.token == token::CloseBrace {
2517 err.span_label(ident_span, "while parsing this `fn`");
2520 Ok(err.emit())
2521 } else if self.token == token::RArrow
2522 && let Some(fn_params_end) = fn_params_end
2523 {
2524 let fn_trait_span =
2530 [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2531 if self.prev_token.is_ident_named(symbol) {
2532 Some(self.prev_token.span)
2533 } else {
2534 None
2535 }
2536 });
2537
2538 let arrow_span = self.token.span;
2543 let ty_span = match self.parse_ret_ty(
2544 AllowPlus::Yes,
2545 RecoverQPath::Yes,
2546 RecoverReturnSign::Yes,
2547 ) {
2548 Ok(ty_span) => ty_span.span().shrink_to_hi(),
2549 Err(parse_error) => {
2550 parse_error.cancel();
2551 return Err(err);
2552 }
2553 };
2554 let ret_ty_span = arrow_span.to(ty_span);
2555
2556 if let Some(fn_trait_span) = fn_trait_span {
2557 err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2560 } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2561 {
2562 err.primary_message(
2566 "return type should be specified after the function parameters",
2567 );
2568 err.subdiagnostic(errors::MisplacedReturnType {
2569 fn_params_end,
2570 snippet,
2571 ret_ty_span,
2572 });
2573 }
2574 Err(err)
2575 } else {
2576 Err(err)
2577 }
2578 }
2579 }
2580 }
2581
2582 fn parse_fn_body(
2586 &mut self,
2587 attrs: &mut AttrVec,
2588 ident: &Ident,
2589 sig_hi: &mut Span,
2590 req_body: bool,
2591 fn_params_end: Option<Span>,
2592 ) -> PResult<'a, Option<Box<Block>>> {
2593 let has_semi = if req_body {
2594 self.token == TokenKind::Semi
2595 } else {
2596 self.check(exp!(Semi))
2598 };
2599 let (inner_attrs, body) = if has_semi {
2600 self.expect_semi()?;
2602 *sig_hi = self.prev_token.span;
2603 (AttrVec::new(), None)
2604 } else if self.check(exp!(OpenBrace)) || self.token.is_metavar_block() {
2605 self.parse_block_common(self.token.span, BlockCheckMode::Default, None)
2606 .map(|(attrs, body)| (attrs, Some(body)))?
2607 } else if self.token == token::Eq {
2608 self.bump(); let eq_sp = self.prev_token.span;
2611 let _ = self.parse_expr()?;
2612 self.expect_semi()?; let span = eq_sp.to(self.prev_token.span);
2614 let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
2615 span,
2616 sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
2617 });
2618 (AttrVec::new(), Some(self.mk_block_err(span, guar)))
2619 } else {
2620 self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
2621 (AttrVec::new(), None)
2622 };
2623 attrs.extend(inner_attrs);
2624 Ok(body)
2625 }
2626
2627 pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
2632 const ALL_QUALS: &[ExpKeywordPair] = &[
2633 exp!(Pub),
2634 exp!(Gen),
2635 exp!(Const),
2636 exp!(Async),
2637 exp!(Unsafe),
2638 exp!(Safe),
2639 exp!(Extern),
2640 ];
2641
2642 let quals: &[_] = if check_pub {
2647 ALL_QUALS
2648 } else {
2649 &[exp!(Gen), exp!(Const), exp!(Async), exp!(Unsafe), exp!(Safe), exp!(Extern)]
2650 };
2651 self.check_keyword_case(exp!(Fn), case) || quals.iter().any(|&exp| self.check_keyword_case(exp, case))
2654 && self.look_ahead(1, |t| {
2655 t.is_keyword_case(kw::Fn, case)
2657 || (
2659 (
2660 t.is_non_raw_ident_where(|i|
2661 quals.iter().any(|exp| exp.kw == i.name)
2662 && i.is_reserved()
2664 )
2665 || case == Case::Insensitive
2666 && t.is_non_raw_ident_where(|i| quals.iter().any(|exp| {
2667 exp.kw.as_str() == i.name.as_str().to_lowercase()
2668 }))
2669 )
2670 && !self.is_unsafe_foreign_mod()
2672 && !self.is_async_gen_block()
2674 && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait])
2676 )
2677 })
2678 || self.check_keyword_case(exp!(Extern), case)
2680 && self.look_ahead(1, |t| t.can_begin_string_literal())
2684 && (self.tree_look_ahead(2, |tt| {
2685 match tt {
2686 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2687 TokenTree::Delimited(..) => false,
2688 }
2689 }) == Some(true) ||
2690 (self.may_recover()
2693 && self.tree_look_ahead(2, |tt| {
2694 match tt {
2695 TokenTree::Token(t, _) =>
2696 ALL_QUALS.iter().any(|exp| {
2697 t.is_keyword(exp.kw)
2698 }),
2699 TokenTree::Delimited(..) => false,
2700 }
2701 }) == Some(true)
2702 && self.tree_look_ahead(3, |tt| {
2703 match tt {
2704 TokenTree::Token(t, _) => t.is_keyword_case(kw::Fn, case),
2705 TokenTree::Delimited(..) => false,
2706 }
2707 }) == Some(true)
2708 )
2709 )
2710 }
2711
2712 pub(super) fn parse_fn_front_matter(
2727 &mut self,
2728 orig_vis: &Visibility,
2729 case: Case,
2730 parsing_mode: FrontMatterParsingMode,
2731 ) -> PResult<'a, FnHeader> {
2732 let sp_start = self.token.span;
2733 let constness = self.parse_constness(case);
2734 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2735 && let Const::Yes(const_span) = constness
2736 {
2737 self.dcx().emit_err(FnPointerCannotBeConst {
2738 span: const_span,
2739 suggestion: const_span.until(self.token.span),
2740 });
2741 }
2742
2743 let async_start_sp = self.token.span;
2744 let coroutine_kind = self.parse_coroutine_kind(case);
2745 if parsing_mode == FrontMatterParsingMode::FunctionPtrType
2746 && let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind
2747 {
2748 self.dcx().emit_err(FnPointerCannotBeAsync {
2749 span: async_span,
2750 suggestion: async_span.until(self.token.span),
2751 });
2752 }
2753 let unsafe_start_sp = self.token.span;
2756 let safety = self.parse_safety(case);
2757
2758 let ext_start_sp = self.token.span;
2759 let ext = self.parse_extern(case);
2760
2761 if let Some(CoroutineKind::Async { span, .. }) = coroutine_kind {
2762 if span.is_rust_2015() {
2763 self.dcx().emit_err(errors::AsyncFnIn2015 {
2764 span,
2765 help: errors::HelpUseLatestEdition::new(),
2766 });
2767 }
2768 }
2769
2770 match coroutine_kind {
2771 Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
2772 self.psess.gated_spans.gate(sym::gen_blocks, span);
2773 }
2774 Some(CoroutineKind::Async { .. }) | None => {}
2775 }
2776
2777 if !self.eat_keyword_case(exp!(Fn), case) {
2778 match self.expect_one_of(&[], &[]) {
2782 Ok(Recovered::Yes(_)) => {}
2783 Ok(Recovered::No) => unreachable!(),
2784 Err(mut err) => {
2785 enum WrongKw {
2787 Duplicated(Span),
2788 Misplaced(Span),
2789 MisplacedDisallowedQualifier,
2794 }
2795
2796 let mut recover_constness = constness;
2798 let mut recover_coroutine_kind = coroutine_kind;
2799 let mut recover_safety = safety;
2800 let wrong_kw = if self.check_keyword(exp!(Const)) {
2803 match constness {
2804 Const::Yes(sp) => Some(WrongKw::Duplicated(sp)),
2805 Const::No => {
2806 recover_constness = Const::Yes(self.token.span);
2807 match parsing_mode {
2808 FrontMatterParsingMode::Function => {
2809 Some(WrongKw::Misplaced(async_start_sp))
2810 }
2811 FrontMatterParsingMode::FunctionPtrType => {
2812 self.dcx().emit_err(FnPointerCannotBeConst {
2813 span: self.token.span,
2814 suggestion: self
2815 .token
2816 .span
2817 .with_lo(self.prev_token.span.hi()),
2818 });
2819 Some(WrongKw::MisplacedDisallowedQualifier)
2820 }
2821 }
2822 }
2823 }
2824 } else if self.check_keyword(exp!(Async)) {
2825 match coroutine_kind {
2826 Some(CoroutineKind::Async { span, .. }) => {
2827 Some(WrongKw::Duplicated(span))
2828 }
2829 Some(CoroutineKind::AsyncGen { span, .. }) => {
2830 Some(WrongKw::Duplicated(span))
2831 }
2832 Some(CoroutineKind::Gen { .. }) => {
2833 recover_coroutine_kind = Some(CoroutineKind::AsyncGen {
2834 span: self.token.span,
2835 closure_id: DUMMY_NODE_ID,
2836 return_impl_trait_id: DUMMY_NODE_ID,
2837 });
2838 Some(WrongKw::Misplaced(unsafe_start_sp))
2840 }
2841 None => {
2842 recover_coroutine_kind = Some(CoroutineKind::Async {
2843 span: self.token.span,
2844 closure_id: DUMMY_NODE_ID,
2845 return_impl_trait_id: DUMMY_NODE_ID,
2846 });
2847 match parsing_mode {
2848 FrontMatterParsingMode::Function => {
2849 Some(WrongKw::Misplaced(async_start_sp))
2850 }
2851 FrontMatterParsingMode::FunctionPtrType => {
2852 self.dcx().emit_err(FnPointerCannotBeAsync {
2853 span: self.token.span,
2854 suggestion: self
2855 .token
2856 .span
2857 .with_lo(self.prev_token.span.hi()),
2858 });
2859 Some(WrongKw::MisplacedDisallowedQualifier)
2860 }
2861 }
2862 }
2863 }
2864 } else if self.check_keyword(exp!(Unsafe)) {
2865 match safety {
2866 Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
2867 Safety::Safe(sp) => {
2868 recover_safety = Safety::Unsafe(self.token.span);
2869 Some(WrongKw::Misplaced(sp))
2870 }
2871 Safety::Default => {
2872 recover_safety = Safety::Unsafe(self.token.span);
2873 Some(WrongKw::Misplaced(ext_start_sp))
2874 }
2875 }
2876 } else if self.check_keyword(exp!(Safe)) {
2877 match safety {
2878 Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
2879 Safety::Unsafe(sp) => {
2880 recover_safety = Safety::Safe(self.token.span);
2881 Some(WrongKw::Misplaced(sp))
2882 }
2883 Safety::Default => {
2884 recover_safety = Safety::Safe(self.token.span);
2885 Some(WrongKw::Misplaced(ext_start_sp))
2886 }
2887 }
2888 } else {
2889 None
2890 };
2891
2892 if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw {
2894 let original_kw = self
2895 .span_to_snippet(original_sp)
2896 .expect("Span extracted directly from keyword should always work");
2897
2898 err.span_suggestion(
2899 self.token_uninterpolated_span(),
2900 format!("`{original_kw}` already used earlier, remove this one"),
2901 "",
2902 Applicability::MachineApplicable,
2903 )
2904 .span_note(original_sp, format!("`{original_kw}` first seen here"));
2905 }
2906 else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
2908 let correct_pos_sp = correct_pos_sp.to(self.prev_token.span);
2909 if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) {
2910 let misplaced_qual_sp = self.token_uninterpolated_span();
2911 let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap();
2912
2913 err.span_suggestion(
2914 correct_pos_sp.to(misplaced_qual_sp),
2915 format!("`{misplaced_qual}` must come before `{current_qual}`"),
2916 format!("{misplaced_qual} {current_qual}"),
2917 Applicability::MachineApplicable,
2918 ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
2919 }
2920 }
2921 else if self.check_keyword(exp!(Pub)) {
2923 let sp = sp_start.to(self.prev_token.span);
2924 if let Ok(snippet) = self.span_to_snippet(sp) {
2925 let current_vis = match self.parse_visibility(FollowedByType::No) {
2926 Ok(v) => v,
2927 Err(d) => {
2928 d.cancel();
2929 return Err(err);
2930 }
2931 };
2932 let vs = pprust::vis_to_string(¤t_vis);
2933 let vs = vs.trim_end();
2934
2935 if matches!(orig_vis.kind, VisibilityKind::Inherited) {
2937 err.span_suggestion(
2938 sp_start.to(self.prev_token.span),
2939 format!("visibility `{vs}` must come before `{snippet}`"),
2940 format!("{vs} {snippet}"),
2941 Applicability::MachineApplicable,
2942 );
2943 }
2944 else {
2946 err.span_suggestion(
2947 current_vis.span,
2948 "there is already a visibility modifier, remove one",
2949 "",
2950 Applicability::MachineApplicable,
2951 )
2952 .span_note(orig_vis.span, "explicit visibility first seen here");
2953 }
2954 }
2955 }
2956
2957 if let Some(wrong_kw) = wrong_kw
2960 && self.may_recover()
2961 && self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
2962 {
2963 self.bump();
2965 self.bump();
2966 if matches!(wrong_kw, WrongKw::MisplacedDisallowedQualifier) {
2969 err.cancel();
2970 } else {
2971 err.emit();
2972 }
2973 return Ok(FnHeader {
2974 constness: recover_constness,
2975 safety: recover_safety,
2976 coroutine_kind: recover_coroutine_kind,
2977 ext,
2978 });
2979 }
2980
2981 return Err(err);
2982 }
2983 }
2984 }
2985
2986 Ok(FnHeader { constness, safety, coroutine_kind, ext })
2987 }
2988
2989 pub(super) fn parse_fn_decl(
2991 &mut self,
2992 fn_parse_mode: &FnParseMode,
2993 ret_allow_plus: AllowPlus,
2994 recover_return_sign: RecoverReturnSign,
2995 ) -> PResult<'a, Box<FnDecl>> {
2996 Ok(Box::new(FnDecl {
2997 inputs: self.parse_fn_params(fn_parse_mode)?,
2998 output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
2999 }))
3000 }
3001
3002 pub(super) fn parse_fn_params(
3004 &mut self,
3005 fn_parse_mode: &FnParseMode,
3006 ) -> PResult<'a, ThinVec<Param>> {
3007 let mut first_param = true;
3008 if self.token != TokenKind::OpenParen
3010 && !self.token.is_keyword(kw::For)
3012 {
3013 self.dcx()
3015 .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() });
3016 return Ok(ThinVec::new());
3017 }
3018
3019 let (mut params, _) = self.parse_paren_comma_seq(|p| {
3020 p.recover_vcs_conflict_marker();
3021 let snapshot = p.create_snapshot_for_diagnostic();
3022 let param = p.parse_param_general(fn_parse_mode, first_param, true).or_else(|e| {
3023 let guar = e.emit();
3024 let lo = if let TokenKind::OpenParen = p.prev_token.kind {
3028 p.prev_token.span.shrink_to_hi()
3029 } else {
3030 p.prev_token.span
3031 };
3032 p.restore_snapshot(snapshot);
3033 p.eat_to_tokens(&[exp!(Comma), exp!(CloseParen)]);
3035 Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
3037 });
3038 first_param = false;
3040 param
3041 })?;
3042 self.deduplicate_recovered_params_names(&mut params);
3044 Ok(params)
3045 }
3046
3047 pub(super) fn parse_param_general(
3052 &mut self,
3053 fn_parse_mode: &FnParseMode,
3054 first_param: bool,
3055 recover_arg_parse: bool,
3056 ) -> PResult<'a, Param> {
3057 let lo = self.token.span;
3058 let attrs = self.parse_outer_attributes()?;
3059 self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
3060 if let Some(mut param) = this.parse_self_param()? {
3062 param.attrs = attrs;
3063 let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
3064 return Ok((res?, Trailing::No, UsePreAttrPos::No));
3065 }
3066
3067 let is_dot_dot_dot = if this.token.kind == token::DotDotDot {
3068 IsDotDotDot::Yes
3069 } else {
3070 IsDotDotDot::No
3071 };
3072 let is_name_required = (fn_parse_mode.req_name)(
3073 this.token.span.with_neighbor(this.prev_token.span).edition(),
3074 is_dot_dot_dot,
3075 );
3076 let is_name_required = if is_name_required && is_dot_dot_dot == IsDotDotDot::Yes {
3077 this.psess.buffer_lint(
3078 VARARGS_WITHOUT_PATTERN,
3079 this.token.span,
3080 ast::CRATE_NODE_ID,
3081 errors::VarargsWithoutPattern { span: this.token.span },
3082 );
3083 false
3084 } else {
3085 is_name_required
3086 };
3087 let (pat, ty) = if is_name_required || this.is_named_param() {
3088 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
3089 let (pat, colon) = this.parse_fn_param_pat_colon()?;
3090 if !colon {
3091 let mut err = this.unexpected().unwrap_err();
3092 return if let Some(ident) = this.parameter_without_type(
3093 &mut err,
3094 pat,
3095 is_name_required,
3096 first_param,
3097 fn_parse_mode,
3098 ) {
3099 let guar = err.emit();
3100 Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No))
3101 } else {
3102 Err(err)
3103 };
3104 }
3105
3106 this.eat_incorrect_doc_comment_for_param_type();
3107 (pat, this.parse_ty_for_param()?)
3108 } else {
3109 debug!("parse_param_general ident_to_pat");
3110 let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
3111 this.eat_incorrect_doc_comment_for_param_type();
3112 let mut ty = this.parse_ty_for_param();
3113
3114 if let Ok(t) = &ty {
3115 if let TyKind::Path(_, Path { segments, .. }) = &t.kind
3117 && let Some(segment) = segments.last()
3118 && let Some(guar) =
3119 this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
3120 {
3121 return Ok((
3122 dummy_arg(segment.ident, guar),
3123 Trailing::No,
3124 UsePreAttrPos::No,
3125 ));
3126 }
3127
3128 if this.token != token::Comma && this.token != token::CloseParen {
3129 ty = this.unexpected_any();
3132 }
3133 }
3134 match ty {
3135 Ok(ty) => {
3136 let pat = this.mk_pat(ty.span, PatKind::Missing);
3137 (Box::new(pat), ty)
3138 }
3139 Err(err) if this.token == token::DotDotDot => return Err(err),
3141 Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err),
3142 Err(err) if recover_arg_parse => {
3143 err.cancel();
3145 this.restore_snapshot(parser_snapshot_before_ty);
3146 this.recover_arg_parse()?
3147 }
3148 Err(err) => return Err(err),
3149 }
3150 };
3151
3152 let span = lo.to(this.prev_token.span);
3153
3154 Ok((
3155 Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty },
3156 Trailing::No,
3157 UsePreAttrPos::No,
3158 ))
3159 })
3160 }
3161
3162 fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
3164 let expect_self_ident = |this: &mut Self| match this.token.ident() {
3166 Some((ident, IdentIsRaw::No)) => {
3167 this.bump();
3168 ident
3169 }
3170 _ => unreachable!(),
3171 };
3172 let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
3174 let is_isolated_self = |this: &Self, n| {
3176 this.is_keyword_ahead(n, &[kw::SelfLower])
3177 && this.look_ahead(n + 1, |t| t != &token::PathSep)
3178 };
3179 let is_isolated_pin_const_self = |this: &Self, n| {
3181 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3182 && this.is_keyword_ahead(n + 1, &[kw::Const])
3183 && is_isolated_self(this, n + 2)
3184 };
3185 let is_isolated_mut_self =
3187 |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
3188 let is_isolated_pin_mut_self = |this: &Self, n| {
3190 this.look_ahead(n, |token| token.is_ident_named(sym::pin))
3191 && is_isolated_mut_self(this, n + 1)
3192 };
3193 let parse_self_possibly_typed = |this: &mut Self, m| {
3195 let eself_ident = expect_self_ident(this);
3196 let eself_hi = this.prev_token.span;
3197 let eself = if this.eat(exp!(Colon)) {
3198 SelfKind::Explicit(this.parse_ty()?, m)
3199 } else {
3200 SelfKind::Value(m)
3201 };
3202 Ok((eself, eself_ident, eself_hi))
3203 };
3204 let expect_self_ident_not_typed =
3205 |this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
3206 let eself_ident = expect_self_ident(this);
3207
3208 if this.may_recover() && this.eat_noexpect(&token::Colon) {
3210 let snap = this.create_snapshot_for_diagnostic();
3211 match this.parse_ty() {
3212 Ok(ty) => {
3213 this.dcx().emit_err(errors::IncorrectTypeOnSelf {
3214 span: ty.span,
3215 move_self_modifier: errors::MoveSelfModifier {
3216 removal_span: modifier_span,
3217 insertion_span: ty.span.shrink_to_lo(),
3218 modifier: modifier.to_ref_suggestion(),
3219 },
3220 });
3221 }
3222 Err(diag) => {
3223 diag.cancel();
3224 this.restore_snapshot(snap);
3225 }
3226 }
3227 }
3228 eself_ident
3229 };
3230 let recover_self_ptr = |this: &mut Self| {
3232 this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
3233
3234 Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
3235 };
3236
3237 let eself_lo = self.token.span;
3241 let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
3242 token::And => {
3243 let has_lifetime = is_lifetime(self, 1);
3244 let skip_lifetime_count = has_lifetime as usize;
3245 let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3246 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3249 SelfKind::Region(lifetime, Mutability::Not)
3250 } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3251 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3254 self.bump(); SelfKind::Region(lifetime, Mutability::Mut)
3256 } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3257 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3260 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3261 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Not)
3264 } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
3265 self.bump(); let lifetime = has_lifetime.then(|| self.expect_lifetime());
3268 self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3269 self.bump(); self.bump(); SelfKind::Pinned(lifetime, Mutability::Mut)
3272 } else {
3273 return Ok(None);
3275 };
3276 let hi = self.token.span;
3277 let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
3278 (eself, self_ident, hi)
3279 }
3280 token::Star if is_isolated_self(self, 1) => {
3282 self.bump();
3283 recover_self_ptr(self)?
3284 }
3285 token::Star
3287 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
3288 {
3289 self.bump();
3290 self.bump();
3291 recover_self_ptr(self)?
3292 }
3293 token::Ident(..) if is_isolated_self(self, 0) => {
3295 parse_self_possibly_typed(self, Mutability::Not)?
3296 }
3297 token::Ident(..) if is_isolated_mut_self(self, 0) => {
3299 self.bump();
3300 parse_self_possibly_typed(self, Mutability::Mut)?
3301 }
3302 _ => return Ok(None),
3303 };
3304
3305 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
3306 Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
3307 }
3308
3309 fn is_named_param(&self) -> bool {
3310 let offset = match &self.token.kind {
3311 token::OpenInvisible(origin) => match origin {
3312 InvisibleOrigin::MetaVar(MetaVarKind::Pat(_)) => {
3313 return self.check_noexpect_past_close_delim(&token::Colon);
3314 }
3315 _ => 0,
3316 },
3317 token::And | token::AndAnd => 1,
3318 _ if self.token.is_keyword(kw::Mut) => 1,
3319 _ => 0,
3320 };
3321
3322 self.look_ahead(offset, |t| t.is_ident())
3323 && self.look_ahead(offset + 1, |t| t == &token::Colon)
3324 }
3325
3326 fn recover_self_param(&mut self) -> bool {
3327 matches!(
3328 self.parse_outer_attributes()
3329 .and_then(|_| self.parse_self_param())
3330 .map_err(|e| e.cancel()),
3331 Ok(Some(_))
3332 )
3333 }
3334}
3335
3336enum IsMacroRulesItem {
3337 Yes { has_bang: bool },
3338 No,
3339}
3340
3341#[derive(Copy, Clone, PartialEq, Eq)]
3342pub(super) enum FrontMatterParsingMode {
3343 Function,
3345 FunctionPtrType,
3348}