1 use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
2 use super::ty::{AllowPlus, RecoverQPath};
3 use super::{FollowedByType, Parser, PathStyle};
5 use crate::maybe_whole;
7 use rustc_ast_pretty::pprust;
8 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult, StashKey};
9 use rustc_span::source_map::{self, Span};
10 use rustc_span::symbol::{kw, sym, Symbol};
11 use syntax::ast::{self, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID};
12 use syntax::ast::{AssocItem, AssocItemKind, Item, ItemKind, UseTree, UseTreeKind};
13 use syntax::ast::{Async, Const, Defaultness, IsAuto, PathSegment, Unsafe};
14 use syntax::ast::{BindingMode, Block, FnDecl, FnSig, Mac, MacArgs, MacDelimiter, Param, SelfKind};
15 use syntax::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData};
16 use syntax::ast::{FnHeader, ForeignItem, Mutability, Visibility, VisibilityKind};
19 use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree};
24 pub(super) type ItemInfo = (Ident, ItemKind);
27 pub fn parse_item(&mut self) -> PResult<'a, Option<P<Item>>> {
28 let attrs = self.parse_outer_attributes()?;
29 self.parse_item_(attrs, true, false)
32 pub(super) fn parse_item_(
34 attrs: Vec<Attribute>,
36 attributes_allowed: bool,
37 ) -> PResult<'a, Option<P<Item>>> {
38 let mut unclosed_delims = vec![];
39 let (ret, tokens) = self.collect_tokens(|this| {
40 let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed);
41 unclosed_delims.append(&mut this.unclosed_delims);
44 self.unclosed_delims.append(&mut unclosed_delims);
46 // Once we've parsed an item and recorded the tokens we got while
47 // parsing we may want to store `tokens` into the item we're about to
48 // return. Note, though, that we specifically didn't capture tokens
49 // related to outer attributes. The `tokens` field here may later be
50 // used with procedural macros to convert this item back into a token
51 // stream, but during expansion we may be removing attributes as we go
54 // If we've got inner attributes then the `tokens` we've got above holds
55 // these inner attributes. If an inner attribute is expanded we won't
56 // actually remove it from the token stream, so we'll just keep yielding
57 // it (bad!). To work around this case for now we just avoid recording
58 // `tokens` if we detect any inner attributes. This should help keep
59 // expansion correct, but we should fix this bug one day!
62 if !i.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
63 i.tokens = Some(tokens);
70 /// Parses one of the items allowed by the flags.
71 fn parse_item_implementation(
73 mut attrs: Vec<Attribute>,
75 attributes_allowed: bool,
76 ) -> PResult<'a, Option<P<Item>>> {
77 maybe_whole!(self, NtItem, |item| {
79 mem::swap(&mut item.attrs, &mut attrs);
80 item.attrs.extend(attrs);
84 let lo = self.token.span;
85 let vis = self.parse_visibility(FollowedByType::No)?;
87 if let Some((ident, kind)) = self.parse_item_kind(&mut attrs, macros_allowed, lo, &vis)? {
88 return Ok(Some(P(self.mk_item(lo, ident, kind, vis, Defaultness::Final, attrs))));
91 // At this point, we have failed to parse an item.
93 self.error_on_unmatched_vis(&vis);
95 if !attributes_allowed {
96 self.recover_attrs_no_item(&attrs)?;
101 /// Error in-case a non-inherited visibility was parsed but no item followed.
102 fn error_on_unmatched_vis(&self, vis: &Visibility) {
103 if let VisibilityKind::Inherited = vis.node {
106 let vs = pprust::vis_to_string(&vis);
107 let vs = vs.trim_end();
108 self.struct_span_err(vis.span, &format!("unmatched visibility `{}`", vs))
109 .span_label(vis.span, "the unmatched visibility")
110 .help(&format!("you likely meant to define an item, e.g., `{} fn foo() {{}}`", vs))
114 /// Parses one of the items allowed by the flags.
117 attrs: &mut Vec<Attribute>,
118 macros_allowed: bool,
121 ) -> PResult<'a, Option<ItemInfo>> {
122 let info = if self.eat_keyword(kw::Use) {
124 let tree = self.parse_use_tree()?;
126 (Ident::invalid(), ItemKind::Use(P(tree)))
127 } else if self.check_fn_front_matter() {
129 let (ident, sig, generics, body) = self.parse_fn(&mut false, attrs, |_| true)?;
130 (ident, ItemKind::Fn(sig, generics, body))
131 } else if self.eat_keyword(kw::Extern) {
132 if self.eat_keyword(kw::Crate) {
134 self.parse_item_extern_crate()?
137 self.parse_item_foreign_mod(attrs)?
139 } else if self.is_static_global() {
141 self.bump(); // `static`
142 let m = self.parse_mutability();
143 self.parse_item_const(Some(m))?
144 } else if let Const::Yes(const_span) = self.parse_constness() {
146 self.recover_const_mut(const_span);
147 self.parse_item_const(None)?
148 } else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() {
150 self.parse_item_trait(attrs, lo)?
151 } else if self.check_keyword(kw::Impl)
152 || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Impl])
153 || self.check_keyword(kw::Default) && self.is_keyword_ahead(1, &[kw::Impl, kw::Unsafe])
156 self.parse_item_impl(attrs)?
157 } else if self.eat_keyword(kw::Mod) {
159 self.parse_item_mod(attrs)?
160 } else if self.eat_keyword(kw::Type) {
162 self.parse_type_alias()?
163 } else if self.eat_keyword(kw::Enum) {
165 self.parse_item_enum()?
166 } else if self.eat_keyword(kw::Struct) {
168 self.parse_item_struct()?
169 } else if self.is_kw_followed_by_ident(kw::Union) {
171 self.bump(); // `union`
172 self.parse_item_union()?
173 } else if self.eat_keyword(kw::Macro) {
175 self.parse_item_decl_macro(lo)?
176 } else if self.is_macro_rules_item() {
178 self.parse_item_macro_rules(vis)?
179 } else if vis.node.is_pub() && self.isnt_macro_invocation() {
180 self.recover_missing_kw_before_item()?;
182 } else if macros_allowed && self.token.is_path_start() {
183 // MACRO INVOCATION ITEM
184 (Ident::invalid(), ItemKind::Mac(self.parse_item_macro(vis)?))
191 /// When parsing a statement, would the start of a path be an item?
192 pub(super) fn is_path_start_item(&mut self) -> bool {
193 self.is_crate_vis() // no: `crate::b`, yes: `crate $item`
194 || self.is_kw_followed_by_ident(kw::Union) // no: `union::b`, yes: `union U { .. }`
195 || self.check_auto_or_unsafe_trait_item() // no: `auto::b`, yes: `auto trait X { .. }`
196 || self.is_async_fn() // no(2015): `async::b`, yes: `async fn`
197 || self.is_macro_rules_item() // no: `macro_rules::b`, yes: `macro_rules! mac`
200 /// Are we sure this could not possibly be a macro invocation?
201 fn isnt_macro_invocation(&mut self) -> bool {
202 self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::ModSep)
205 /// Recover on encountering a struct or method definition where the user
206 /// forgot to add the `struct` or `fn` keyword after writing `pub`: `pub S {}`.
207 fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
208 // Space between `pub` keyword and the identifier
211 // ^^^ `sp` points here
212 let sp = self.prev_span.between(self.token.span);
213 let full_sp = self.prev_span.to(self.token.span);
214 let ident_sp = self.token.span;
215 if self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) {
216 // possible public struct definition where `struct` was forgotten
217 let ident = self.parse_ident().unwrap();
218 let msg = format!("add `struct` here to parse `{}` as a public struct", ident);
219 let mut err = self.struct_span_err(sp, "missing `struct` for struct definition");
220 err.span_suggestion_short(
224 Applicability::MaybeIncorrect, // speculative
227 } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
228 let ident = self.parse_ident().unwrap();
230 let kw_name = self.recover_first_param();
231 self.consume_block(token::Paren, ConsumeClosingDelim::Yes);
232 let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
233 self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
235 ("fn", kw_name, false)
236 } else if self.check(&token::OpenDelim(token::Brace)) {
238 ("fn", kw_name, false)
239 } else if self.check(&token::Colon) {
243 ("fn` or `struct", "function or struct", true)
246 let msg = format!("missing `{}` for {} definition", kw, kw_name);
247 let mut err = self.struct_span_err(sp, &msg);
249 self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
251 format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name);
252 err.span_suggestion_short(
256 Applicability::MachineApplicable,
259 if let Ok(snippet) = self.span_to_snippet(ident_sp) {
262 "if you meant to call a macro, try",
263 format!("{}!", snippet),
264 // this is the `ambiguous` conditional branch
265 Applicability::MaybeIncorrect,
269 "if you meant to call a macro, remove the `pub` \
270 and add a trailing `!` after the identifier",
275 } else if self.look_ahead(1, |t| *t == token::Lt) {
276 let ident = self.parse_ident().unwrap();
277 self.eat_to_tokens(&[&token::Gt]);
279 let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
280 ("fn", self.recover_first_param(), false)
281 } else if self.check(&token::OpenDelim(token::Brace)) {
282 ("struct", "struct", false)
284 ("fn` or `struct", "function or struct", true)
286 let msg = format!("missing `{}` for {} definition", kw, kw_name);
287 let mut err = self.struct_span_err(sp, &msg);
289 err.span_suggestion_short(
291 &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
293 Applicability::MachineApplicable,
302 /// Parses an item macro, e.g., `item!();`.
303 fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, Mac> {
304 let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
305 self.expect(&token::Not)?; // `!`
306 let args = self.parse_mac_args()?; // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
307 self.eat_semi_for_macro_if_needed(&args);
308 self.complain_if_pub_macro(vis, false);
309 Ok(Mac { path, args, prior_type_ascription: self.last_type_ascription })
312 /// Recover if we parsed attributes and expected an item but there was none.
313 fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
314 let (start, end) = match attrs {
317 [x0, .., xn] => (x0, xn),
319 let msg = if end.is_doc_comment() {
320 "expected item after doc comment"
322 "expected item after attributes"
324 let mut err = self.struct_span_err(end.span, msg);
325 if end.is_doc_comment() {
326 err.span_label(end.span, "this doc comment doesn't document anything");
328 if let [.., penultimate, _] = attrs {
329 err.span_label(start.span.to(penultimate.span), "other attributes here");
334 fn is_async_fn(&self) -> bool {
335 self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
338 /// Given this code `path(`, it seems like this is not
339 /// setting the visibility of a macro invocation,
340 /// but rather a mistyped method declaration.
341 /// Create a diagnostic pointing out that `fn` is missing.
344 /// x | pub path(&self) {
345 /// | ^ missing `fn`, `type`, `const`, or `static`
347 fn missing_nested_item_kind_err(&self, prev_span: Span) -> DiagnosticBuilder<'a> {
348 let sp = prev_span.between(self.token.span);
349 let expected_kinds = "missing `fn`, `type`, `const`, or `static`";
350 let mut err = self.struct_span_err(sp, &format!("{} for item declaration", expected_kinds));
351 err.span_label(sp, expected_kinds);
355 /// Parses an implementation item.
358 /// impl<'a, T> TYPE { /* impl items */ }
359 /// impl<'a, T> TRAIT for TYPE { /* impl items */ }
360 /// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
361 /// impl<'a, T> const TRAIT for TYPE { /* impl items */ }
364 /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
366 /// "impl" GENERICS "const"? "!"? TYPE "for"? (TYPE | "..") ("where" PREDICATES)? "{" BODY "}"
367 /// "impl" GENERICS "const"? "!"? TYPE ("where" PREDICATES)? "{" BODY "}"
369 fn parse_item_impl(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
370 let defaultness = self.parse_defaultness();
371 let unsafety = self.parse_unsafety();
372 self.expect_keyword(kw::Impl)?;
374 // First, parse generic parameters if necessary.
375 let mut generics = if self.choose_generics_over_qpath() {
376 self.parse_generics()?
378 let mut generics = Generics::default();
380 // /\ this is where `generics.span` should point when there are no type params.
381 generics.span = self.prev_span.shrink_to_hi();
385 let constness = self.parse_constness();
386 if let Const::Yes(span) = constness {
387 self.sess.gated_spans.gate(sym::const_trait_impl, span);
390 // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
391 let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
393 ast::ImplPolarity::Negative
395 ast::ImplPolarity::Positive
398 // Parse both types and traits as a type, then reinterpret if necessary.
399 let err_path = |span| ast::Path::from_ident(Ident::new(kw::Invalid, span));
400 let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
402 let span = self.prev_span.between(self.token.span);
403 self.struct_span_err(span, "missing trait in a trait impl").emit();
404 P(Ty { kind: TyKind::Path(None, err_path(span)), span, id: DUMMY_NODE_ID })
409 // If `for` is missing we try to recover.
410 let has_for = self.eat_keyword(kw::For);
411 let missing_for_span = self.prev_span.between(self.token.span);
413 let ty_second = if self.token == token::DotDot {
414 // We need to report this error after `cfg` expansion for compatibility reasons
415 self.bump(); // `..`, do not add it to expected tokens
416 Some(self.mk_ty(self.prev_span, TyKind::Err))
417 } else if has_for || self.token.can_begin_type() {
418 Some(self.parse_ty()?)
423 generics.where_clause = self.parse_where_clause()?;
425 let impl_items = self.parse_item_list(attrs, |p, at_end| p.parse_impl_item(at_end))?;
427 let item_kind = match ty_second {
429 // impl Trait for Type
431 self.struct_span_err(missing_for_span, "missing `for` in a trait impl")
432 .span_suggestion_short(
436 Applicability::MachineApplicable,
441 let ty_first = ty_first.into_inner();
442 let path = match ty_first.kind {
443 // This notably includes paths passed through `ty` macro fragments (#46438).
444 TyKind::Path(None, path) => path,
446 self.struct_span_err(ty_first.span, "expected a trait, found type").emit();
447 err_path(ty_first.span)
450 let trait_ref = TraitRef { path, ref_id: ty_first.id };
458 of_trait: Some(trait_ref),
478 Ok((Ident::invalid(), item_kind))
481 fn parse_item_list<T>(
483 attrs: &mut Vec<Attribute>,
484 mut parse_item: impl FnMut(&mut Parser<'a>, &mut bool) -> PResult<'a, T>,
485 ) -> PResult<'a, Vec<T>> {
486 self.expect(&token::OpenDelim(token::Brace))?;
487 attrs.append(&mut self.parse_inner_attributes()?);
489 let mut items = Vec::new();
490 while !self.eat(&token::CloseDelim(token::Brace)) {
491 if self.recover_doc_comment_before_brace() {
494 let mut at_end = false;
495 match parse_item(self, &mut at_end) {
496 Ok(item) => items.push(item),
500 self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
509 /// Recover on a doc comment before `}`.
510 fn recover_doc_comment_before_brace(&mut self) -> bool {
511 if let token::DocComment(_) = self.token.kind {
512 if self.look_ahead(1, |tok| tok == &token::CloseDelim(token::Brace)) {
517 "found a documentation comment that doesn't document anything",
519 .span_label(self.token.span, "this doc comment doesn't document anything")
521 "doc comments must come before what they document, maybe a \
522 comment was intended with `//`?",
532 /// Parses defaultness (i.e., `default` or nothing).
533 fn parse_defaultness(&mut self) -> Defaultness {
534 // We are interested in `default` followed by another keyword.
535 // However, we must avoid keywords that occur as binary operators.
536 // Currently, the only applicable keyword is `as` (`default as Ty`).
537 if self.check_keyword(kw::Default)
538 && self.look_ahead(1, |t| {
539 t.is_non_raw_ident_where(|i| i.is_reserved() && i.name != kw::As)
542 self.bump(); // `default`
543 Defaultness::Default(self.prev_span)
549 /// Is this an `(unsafe auto? | auto) trait` item?
550 fn check_auto_or_unsafe_trait_item(&mut self) -> bool {
552 self.check_keyword(kw::Auto) && self.is_keyword_ahead(1, &[kw::Trait])
554 || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
557 /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
558 fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<'a, ItemInfo> {
559 let unsafety = self.parse_unsafety();
560 // Parse optional `auto` prefix.
561 let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No };
563 self.expect_keyword(kw::Trait)?;
564 let ident = self.parse_ident()?;
565 let mut tps = self.parse_generics()?;
567 // Parse optional colon and supertrait bounds.
568 let had_colon = self.eat(&token::Colon);
569 let span_at_colon = self.prev_span;
571 if had_colon { self.parse_generic_bounds(Some(self.prev_span))? } else { Vec::new() };
573 let span_before_eq = self.prev_span;
574 if self.eat(&token::Eq) {
575 // It's a trait alias.
577 let span = span_at_colon.to(span_before_eq);
578 self.struct_span_err(span, "bounds are not allowed on trait aliases").emit();
581 let bounds = self.parse_generic_bounds(None)?;
582 tps.where_clause = self.parse_where_clause()?;
585 let whole_span = lo.to(self.prev_span);
586 if is_auto == IsAuto::Yes {
587 let msg = "trait aliases cannot be `auto`";
588 self.struct_span_err(whole_span, msg).span_label(whole_span, msg).emit();
590 if let Unsafe::Yes(_) = unsafety {
591 let msg = "trait aliases cannot be `unsafe`";
592 self.struct_span_err(whole_span, msg).span_label(whole_span, msg).emit();
595 self.sess.gated_spans.gate(sym::trait_alias, whole_span);
597 Ok((ident, ItemKind::TraitAlias(tps, bounds)))
599 // It's a normal trait.
600 tps.where_clause = self.parse_where_clause()?;
601 let items = self.parse_item_list(attrs, |p, at_end| p.parse_trait_item(at_end))?;
602 Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, items)))
606 pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, P<AssocItem>> {
607 maybe_whole!(self, NtImplItem, |x| x);
608 self.parse_assoc_item(at_end, |_| true)
611 pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, P<AssocItem>> {
612 maybe_whole!(self, NtTraitItem, |x| x);
613 // This is somewhat dubious; We don't want to allow
614 // param names to be left off if there is a definition...
616 // We don't allow param names to be left off in edition 2018.
617 self.parse_assoc_item(at_end, |t| t.span.rust_2018())
620 /// Parses associated items.
625 ) -> PResult<'a, P<AssocItem>> {
626 let attrs = self.parse_outer_attributes()?;
627 let mut unclosed_delims = vec![];
628 let (mut item, tokens) = self.collect_tokens(|this| {
629 let item = this.parse_assoc_item_(at_end, attrs, req_name);
630 unclosed_delims.append(&mut this.unclosed_delims);
633 self.unclosed_delims.append(&mut unclosed_delims);
634 // See `parse_item` for why this clause is here.
635 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
636 item.tokens = Some(tokens);
638 self.error_on_assoc_static(&item);
642 fn error_on_assoc_static(&self, item: &AssocItem) {
643 if let AssocItemKind::Static(..) = item.kind {
644 self.struct_span_err(item.span, "associated `static` items are not allowed").emit();
648 fn parse_assoc_item_(
651 mut attrs: Vec<Attribute>,
653 ) -> PResult<'a, AssocItem> {
654 let lo = self.token.span;
655 let vis = self.parse_visibility(FollowedByType::No)?;
656 let defaultness = self.parse_defaultness();
657 let (ident, kind) = self.parse_assoc_item_kind(at_end, &mut attrs, req_name, &vis)?;
658 let span = lo.to(self.prev_span);
659 let id = DUMMY_NODE_ID;
660 Ok(AssocItem { id, span, ident, attrs, vis, defaultness, kind, tokens: None })
663 fn parse_assoc_item_kind(
666 attrs: &mut Vec<Attribute>,
669 ) -> PResult<'a, (Ident, AssocItemKind)> {
670 if self.eat_keyword(kw::Type) {
671 match self.parse_type_alias()? {
672 (ident, ItemKind::TyAlias(a, b, c)) => Ok((ident, AssocItemKind::TyAlias(a, b, c))),
675 } else if self.check_fn_front_matter() {
676 let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, req_name)?;
677 Ok((ident, AssocItemKind::Fn(sig, generics, body)))
678 } else if self.is_static_global() {
679 self.bump(); // `static`
680 let mutbl = self.parse_mutability();
681 let (ident, ty, expr) = self.parse_item_const_common(Some(mutbl))?;
682 Ok((ident, AssocItemKind::Static(ty, mutbl, expr)))
683 } else if self.eat_keyword(kw::Const) {
684 let (ident, ty, expr) = self.parse_item_const_common(None)?;
685 Ok((ident, AssocItemKind::Const(ty, expr)))
686 } else if self.isnt_macro_invocation() {
687 Err(self.missing_nested_item_kind_err(self.prev_span))
688 } else if self.token.is_path_start() {
689 let mac = self.parse_item_macro(&vis)?;
691 Ok((Ident::invalid(), AssocItemKind::Macro(mac)))
693 self.recover_attrs_no_item(attrs)?;
698 /// Parses a `type` alias with the following grammar:
700 /// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
702 /// The `"type"` has already been eaten.
703 fn parse_type_alias(&mut self) -> PResult<'a, (Ident, ItemKind)> {
704 let ident = self.parse_ident()?;
705 let mut generics = self.parse_generics()?;
707 // Parse optional colon and param bounds.
709 if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
710 generics.where_clause = self.parse_where_clause()?;
712 let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
715 Ok((ident, ItemKind::TyAlias(generics, bounds, default)))
718 /// Parses a `UseTree`.
721 /// USE_TREE = [`::`] `*` |
722 /// [`::`] `{` USE_TREE_LIST `}` |
724 /// PATH `::` `{` USE_TREE_LIST `}` |
725 /// PATH [`as` IDENT]
727 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
728 let lo = self.token.span;
730 let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
731 let kind = if self.check(&token::OpenDelim(token::Brace))
732 || self.check(&token::BinOp(token::Star))
733 || self.is_import_coupler()
735 // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
736 let mod_sep_ctxt = self.token.span.ctxt();
737 if self.eat(&token::ModSep) {
740 .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
743 self.parse_use_tree_glob_or_nested()?
745 // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
746 prefix = self.parse_path(PathStyle::Mod)?;
748 if self.eat(&token::ModSep) {
749 self.parse_use_tree_glob_or_nested()?
751 UseTreeKind::Simple(self.parse_rename()?, DUMMY_NODE_ID, DUMMY_NODE_ID)
755 Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) })
758 /// Parses `*` or `{...}`.
759 fn parse_use_tree_glob_or_nested(&mut self) -> PResult<'a, UseTreeKind> {
760 Ok(if self.eat(&token::BinOp(token::Star)) {
763 UseTreeKind::Nested(self.parse_use_tree_list()?)
767 /// Parses a `UseTreeKind::Nested(list)`.
770 /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
772 fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
773 self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, DUMMY_NODE_ID)))
777 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
778 if self.eat_keyword(kw::As) { self.parse_ident_or_underscore().map(Some) } else { Ok(None) }
781 fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
782 match self.token.kind {
783 token::Ident(name @ kw::Underscore, false) => {
784 let span = self.token.span;
786 Ok(Ident::new(name, span))
788 _ => self.parse_ident(),
792 /// Parses `extern crate` links.
797 /// extern crate foo;
798 /// extern crate bar as foo;
800 fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemInfo> {
801 // Accept `extern crate name-like-this` for better diagnostics
802 let orig_name = self.parse_crate_name_with_dashes()?;
803 let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
804 (rename, Some(orig_name.name))
809 Ok((item_name, ItemKind::ExternCrate(orig_name)))
812 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
813 let error_msg = "crate name using dashes are not valid in `extern crate` statements";
814 let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
816 let mut ident = if self.token.is_keyword(kw::SelfLower) {
817 self.parse_path_segment_ident()
821 let mut idents = vec![];
822 let mut replacement = vec![];
823 let mut fixed_crate_name = false;
824 // Accept `extern crate name-like-this` for better diagnostics.
825 let dash = token::BinOp(token::BinOpToken::Minus);
826 if self.token == dash {
827 // Do not include `-` as part of the expected tokens list.
828 while self.eat(&dash) {
829 fixed_crate_name = true;
830 replacement.push((self.prev_span, "_".to_string()));
831 idents.push(self.parse_ident()?);
834 if fixed_crate_name {
835 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
836 let mut fixed_name = format!("{}", ident.name);
838 fixed_name.push_str(&format!("_{}", part.name));
840 ident = Ident::from_str_and_span(&fixed_name, fixed_name_sp);
842 self.struct_span_err(fixed_name_sp, error_msg)
843 .span_label(fixed_name_sp, "dash-separated idents are not valid")
844 .multipart_suggestion(suggestion_msg, replacement, Applicability::MachineApplicable)
850 /// Parses `extern` for foreign ABIs modules.
852 /// `extern` is expected to have been consumed before calling this method.
856 /// ```ignore (only-for-syntax-highlight)
860 fn parse_item_foreign_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
861 let abi = self.parse_abi(); // ABI?
862 let items = self.parse_item_list(attrs, |p, at_end| p.parse_foreign_item(at_end))?;
863 let module = ast::ForeignMod { abi, items };
864 Ok((Ident::invalid(), ItemKind::ForeignMod(module)))
867 /// Parses a foreign item (one in an `extern { ... }` block).
868 pub fn parse_foreign_item(&mut self, at_end: &mut bool) -> PResult<'a, P<ForeignItem>> {
869 maybe_whole!(self, NtForeignItem, |ni| ni);
871 let mut attrs = self.parse_outer_attributes()?;
872 let lo = self.token.span;
873 let vis = self.parse_visibility(FollowedByType::No)?;
874 let (ident, kind) = self.parse_assoc_item_kind(at_end, &mut attrs, |_| true, &vis)?;
875 let item = self.mk_item(lo, ident, kind, vis, Defaultness::Final, attrs);
876 self.error_on_foreign_const(&item);
880 fn error_on_foreign_const(&self, item: &ForeignItem) {
881 if let AssocItemKind::Const(..) = item.kind {
882 self.struct_span_err(item.ident.span, "extern items cannot be `const`")
884 item.span.with_hi(item.ident.span.lo()),
885 "try using a static value",
886 "static ".to_string(),
887 Applicability::MachineApplicable,
890 "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html",
896 fn is_static_global(&mut self) -> bool {
897 if self.check_keyword(kw::Static) {
898 // Check if this could be a closure.
899 !self.look_ahead(1, |token| {
900 if token.is_keyword(kw::Move) {
904 token::BinOp(token::Or) | token::OrOr => true,
913 /// Recover on `const mut` with `const` already eaten.
914 fn recover_const_mut(&mut self, const_span: Span) {
915 if self.eat_keyword(kw::Mut) {
916 let span = self.prev_span;
917 self.struct_span_err(span, "const globals cannot be mutable")
918 .span_label(span, "cannot be mutable")
921 "you might want to declare a static instead",
923 Applicability::MaybeIncorrect,
929 /// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with
930 /// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
932 /// When `m` is `"const"`, `$ident` may also be `"_"`.
933 fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
934 let (id, ty, expr) = self.parse_item_const_common(m)?;
936 Some(m) => ItemKind::Static(ty, m, expr),
937 None => ItemKind::Const(ty, expr),
942 /// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with
943 /// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
945 /// When `m` is `"const"`, `$ident` may also be `"_"`.
946 fn parse_item_const_common(
948 m: Option<Mutability>,
949 ) -> PResult<'a, (Ident, P<Ty>, Option<P<ast::Expr>>)> {
950 let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
952 // Parse the type of a `const` or `static mut?` item.
953 // That is, the `":" $ty` fragment.
954 let ty = if self.eat(&token::Colon) {
957 self.recover_missing_const_type(id, m)
960 let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None };
965 /// We were supposed to parse `:` but the `:` was missing.
966 /// This means that the type is missing.
967 fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
968 // Construct the error and stash it away with the hope
969 // that typeck will later enrich the error with a type.
971 Some(Mutability::Mut) => "static mut",
972 Some(Mutability::Not) => "static",
975 let mut err = self.struct_span_err(id.span, &format!("missing type for `{}` item", kind));
978 "provide a type for the item",
979 format!("{}: <type>", id),
980 Applicability::HasPlaceholders,
982 err.stash(id.span, StashKey::ItemNoType);
984 // The user intended that the type be inferred,
985 // so treat this as if the user wrote e.g. `const A: _ = expr;`.
986 P(Ty { kind: TyKind::Infer, span: id.span, id: ast::DUMMY_NODE_ID })
989 /// Parses an enum declaration.
990 fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
991 let id = self.parse_ident()?;
992 let mut generics = self.parse_generics()?;
993 generics.where_clause = self.parse_where_clause()?;
996 self.parse_delim_comma_seq(token::Brace, |p| p.parse_enum_variant()).map_err(|e| {
1001 let enum_definition =
1002 EnumDef { variants: variants.into_iter().filter_map(|v| v).collect() };
1003 Ok((id, ItemKind::Enum(enum_definition, generics)))
1006 fn parse_enum_variant(&mut self) -> PResult<'a, Option<Variant>> {
1007 let variant_attrs = self.parse_outer_attributes()?;
1008 let vlo = self.token.span;
1010 let vis = self.parse_visibility(FollowedByType::No)?;
1011 if !self.recover_nested_adt_item(kw::Enum)? {
1014 let ident = self.parse_ident()?;
1016 let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
1017 // Parse a struct variant.
1018 let (fields, recovered) = self.parse_record_struct_body()?;
1019 VariantData::Struct(fields, recovered)
1020 } else if self.check(&token::OpenDelim(token::Paren)) {
1021 VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID)
1023 VariantData::Unit(DUMMY_NODE_ID)
1027 if self.eat(&token::Eq) { Some(self.parse_anon_const_expr()?) } else { None };
1029 let vr = ast::Variant {
1033 attrs: variant_attrs,
1036 span: vlo.to(self.prev_span),
1037 is_placeholder: false,
1043 /// Parses `struct Foo { ... }`.
1044 fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
1045 let class_name = self.parse_ident()?;
1047 let mut generics = self.parse_generics()?;
1049 // There is a special case worth noting here, as reported in issue #17904.
1050 // If we are parsing a tuple struct it is the case that the where clause
1051 // should follow the field list. Like so:
1053 // struct Foo<T>(T) where T: Copy;
1055 // If we are parsing a normal record-style struct it is the case
1056 // that the where clause comes before the body, and after the generics.
1057 // So if we look ahead and see a brace or a where-clause we begin
1058 // parsing a record style struct.
1060 // Otherwise if we look ahead and see a paren we parse a tuple-style
1063 let vdata = if self.token.is_keyword(kw::Where) {
1064 generics.where_clause = self.parse_where_clause()?;
1065 if self.eat(&token::Semi) {
1066 // If we see a: `struct Foo<T> where T: Copy;` style decl.
1067 VariantData::Unit(DUMMY_NODE_ID)
1069 // If we see: `struct Foo<T> where T: Copy { ... }`
1070 let (fields, recovered) = self.parse_record_struct_body()?;
1071 VariantData::Struct(fields, recovered)
1073 // No `where` so: `struct Foo<T>;`
1074 } else if self.eat(&token::Semi) {
1075 VariantData::Unit(DUMMY_NODE_ID)
1076 // Record-style struct definition
1077 } else if self.token == token::OpenDelim(token::Brace) {
1078 let (fields, recovered) = self.parse_record_struct_body()?;
1079 VariantData::Struct(fields, recovered)
1080 // Tuple-style struct definition with optional where-clause.
1081 } else if self.token == token::OpenDelim(token::Paren) {
1082 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1083 generics.where_clause = self.parse_where_clause()?;
1084 self.expect_semi()?;
1087 let token_str = super::token_descr(&self.token);
1089 "expected `where`, `{{`, `(`, or `;` after struct name, found {}",
1092 let mut err = self.struct_span_err(self.token.span, msg);
1093 err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name");
1097 Ok((class_name, ItemKind::Struct(vdata, generics)))
1100 /// Parses `union Foo { ... }`.
1101 fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
1102 let class_name = self.parse_ident()?;
1104 let mut generics = self.parse_generics()?;
1106 let vdata = if self.token.is_keyword(kw::Where) {
1107 generics.where_clause = self.parse_where_clause()?;
1108 let (fields, recovered) = self.parse_record_struct_body()?;
1109 VariantData::Struct(fields, recovered)
1110 } else if self.token == token::OpenDelim(token::Brace) {
1111 let (fields, recovered) = self.parse_record_struct_body()?;
1112 VariantData::Struct(fields, recovered)
1114 let token_str = super::token_descr(&self.token);
1115 let msg = &format!("expected `where` or `{{` after union name, found {}", token_str);
1116 let mut err = self.struct_span_err(self.token.span, msg);
1117 err.span_label(self.token.span, "expected `where` or `{` after union name");
1121 Ok((class_name, ItemKind::Union(vdata, generics)))
1124 fn parse_record_struct_body(
1126 ) -> PResult<'a, (Vec<StructField>, /* recovered */ bool)> {
1127 let mut fields = Vec::new();
1128 let mut recovered = false;
1129 if self.eat(&token::OpenDelim(token::Brace)) {
1130 while self.token != token::CloseDelim(token::Brace) {
1131 let field = self.parse_struct_decl_field().map_err(|e| {
1132 self.consume_block(token::Brace, ConsumeClosingDelim::No);
1137 Ok(field) => fields.push(field),
1144 self.eat(&token::CloseDelim(token::Brace));
1146 let token_str = super::token_descr(&self.token);
1147 let msg = &format!("expected `where`, or `{{` after struct name, found {}", token_str);
1148 let mut err = self.struct_span_err(self.token.span, msg);
1149 err.span_label(self.token.span, "expected `where`, or `{` after struct name");
1153 Ok((fields, recovered))
1156 fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
1157 // This is the case where we find `struct Foo<T>(T) where T: Copy;`
1158 // Unit like structs are handled in parse_item_struct function
1159 self.parse_paren_comma_seq(|p| {
1160 let attrs = p.parse_outer_attributes()?;
1161 let lo = p.token.span;
1162 let vis = p.parse_visibility(FollowedByType::Yes)?;
1163 let ty = p.parse_ty()?;
1165 span: lo.to(ty.span),
1171 is_placeholder: false,
1177 /// Parses an element of a struct declaration.
1178 fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
1179 let attrs = self.parse_outer_attributes()?;
1180 let lo = self.token.span;
1181 let vis = self.parse_visibility(FollowedByType::No)?;
1182 self.parse_single_struct_field(lo, vis, attrs)
1185 /// Parses a structure field declaration.
1186 fn parse_single_struct_field(
1190 attrs: Vec<Attribute>,
1191 ) -> PResult<'a, StructField> {
1192 let mut seen_comma: bool = false;
1193 let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
1194 if self.token == token::Comma {
1197 match self.token.kind {
1201 token::CloseDelim(token::Brace) => {}
1202 token::DocComment(_) => {
1203 let previous_span = self.prev_span;
1204 let mut err = self.span_fatal_err(self.token.span, Error::UselessDocComment);
1205 self.bump(); // consume the doc comment
1206 let comma_after_doc_seen = self.eat(&token::Comma);
1207 // `seen_comma` is always false, because we are inside doc block
1208 // condition is here to make code more readable
1209 if seen_comma == false && comma_after_doc_seen == true {
1212 if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) {
1215 if seen_comma == false {
1216 let sp = self.sess.source_map().next_point(previous_span);
1217 err.span_suggestion(
1219 "missing comma here",
1221 Applicability::MachineApplicable,
1228 let sp = self.prev_span.shrink_to_hi();
1229 let mut err = self.struct_span_err(
1231 &format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
1233 if self.token.is_ident() {
1234 // This is likely another field; emit the diagnostic and keep going
1235 err.span_suggestion(
1237 "try adding a comma",
1239 Applicability::MachineApplicable,
1250 /// Parses a structure field.
1251 fn parse_name_and_ty(
1255 attrs: Vec<Attribute>,
1256 ) -> PResult<'a, StructField> {
1257 let name = self.parse_ident()?;
1258 self.expect(&token::Colon)?;
1259 let ty = self.parse_ty()?;
1261 span: lo.to(self.prev_span),
1267 is_placeholder: false,
1271 /// Parses a declarative macro 2.0 definition.
1272 /// The `macro` keyword has already been parsed.
1274 /// MacBody = "{" TOKEN_STREAM "}" ;
1275 /// MacParams = "(" TOKEN_STREAM ")" ;
1276 /// DeclMac = "macro" Ident MacParams? MacBody ;
1278 fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> {
1279 let ident = self.parse_ident()?;
1280 let body = if self.check(&token::OpenDelim(token::Brace)) {
1281 self.parse_mac_args()? // `MacBody`
1282 } else if self.check(&token::OpenDelim(token::Paren)) {
1283 let params = self.parse_token_tree(); // `MacParams`
1284 let pspan = params.span();
1285 if !self.check(&token::OpenDelim(token::Brace)) {
1286 return self.unexpected();
1288 let body = self.parse_token_tree(); // `MacBody`
1289 // Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
1290 let bspan = body.span();
1291 let arrow = TokenTree::token(token::FatArrow, pspan.between(bspan)); // `=>`
1292 let tokens = TokenStream::new(vec![params.into(), arrow.into(), body.into()]);
1293 let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
1294 P(MacArgs::Delimited(dspan, MacDelimiter::Brace, tokens))
1296 return self.unexpected();
1299 self.sess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_span));
1300 Ok((ident, ItemKind::MacroDef(ast::MacroDef { body, legacy: false })))
1303 /// Is this unambiguously the start of a `macro_rules! foo` item defnition?
1304 fn is_macro_rules_item(&mut self) -> bool {
1305 self.check_keyword(kw::MacroRules)
1306 && self.look_ahead(1, |t| *t == token::Not)
1307 && self.look_ahead(2, |t| t.is_ident())
1310 /// Parses a legacy `macro_rules! foo { ... }` declarative macro.
1311 fn parse_item_macro_rules(&mut self, vis: &Visibility) -> PResult<'a, ItemInfo> {
1312 self.expect_keyword(kw::MacroRules)?; // `macro_rules`
1313 self.expect(&token::Not)?; // `!`
1315 let ident = self.parse_ident()?;
1316 let body = self.parse_mac_args()?;
1317 self.eat_semi_for_macro_if_needed(&body);
1318 self.complain_if_pub_macro(vis, true);
1320 Ok((ident, ItemKind::MacroDef(ast::MacroDef { body, legacy: true })))
1323 /// Item macro invocations or `macro_rules!` definitions need inherited visibility.
1324 /// If that's not the case, emit an error.
1325 fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
1326 if let VisibilityKind::Inherited = vis.node {
1330 let vstr = pprust::vis_to_string(vis);
1331 let vstr = vstr.trim_end();
1333 let msg = format!("can't qualify macro_rules invocation with `{}`", vstr);
1334 self.struct_span_err(vis.span, &msg)
1337 "try exporting the macro",
1338 "#[macro_export]".to_owned(),
1339 Applicability::MaybeIncorrect, // speculative
1343 self.struct_span_err(vis.span, "can't qualify macro invocation with `pub`")
1346 "remove the visibility",
1348 Applicability::MachineApplicable,
1350 .help(&format!("try adjusting the macro to put `{}` inside the invocation", vstr))
1355 fn eat_semi_for_macro_if_needed(&mut self, args: &MacArgs) {
1356 if args.need_semicolon() && !self.eat(&token::Semi) {
1357 self.report_invalid_macro_expansion_item(args);
1361 fn report_invalid_macro_expansion_item(&self, args: &MacArgs) {
1362 let span = args.span().expect("undelimited macro call");
1363 let mut err = self.struct_span_err(
1365 "macros that expand to items must be delimited with braces or followed by a semicolon",
1367 if self.unclosed_delims.is_empty() {
1368 let DelimSpan { open, close } = match args {
1369 MacArgs::Empty | MacArgs::Eq(..) => unreachable!(),
1370 MacArgs::Delimited(dspan, ..) => *dspan,
1372 err.multipart_suggestion(
1373 "change the delimiters to curly braces",
1374 vec![(open, "{".to_string()), (close, '}'.to_string())],
1375 Applicability::MaybeIncorrect,
1378 err.span_suggestion(
1380 "change the delimiters to curly braces",
1381 " { /* items */ }".to_string(),
1382 Applicability::HasPlaceholders,
1385 err.span_suggestion(
1386 span.shrink_to_hi(),
1389 Applicability::MaybeIncorrect,
1394 /// Checks if current token is one of tokens which cannot be nested like `kw::Enum`. In case
1395 /// it is, we try to parse the item and report error about nested types.
1396 fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
1397 if (self.token.is_keyword(kw::Enum)
1398 || self.token.is_keyword(kw::Struct)
1399 || self.token.is_keyword(kw::Union))
1400 && self.look_ahead(1, |t| t.is_ident())
1402 let kw_token = self.token.clone();
1403 let kw_str = pprust::token_to_string(&kw_token);
1404 let item = self.parse_item()?;
1406 self.struct_span_err(
1408 &format!("`{}` definition cannot be nested inside `{}`", kw_str, keyword),
1412 &format!("consider creating a new `{}` definition instead of nesting", kw_str),
1414 Applicability::MaybeIncorrect,
1417 // We successfully parsed the item but we must inform the caller about nested problem.
1429 defaultness: Defaultness,
1430 attrs: Vec<Attribute>,
1432 let span = lo.to(self.prev_span);
1433 Item { ident, attrs, id: DUMMY_NODE_ID, kind, vis, defaultness, span, tokens: None }
1437 /// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
1439 /// The function decides if, per-parameter `p`, `p` must have a pattern or just a type.
1440 type ReqName = fn(&token::Token) -> bool;
1442 /// Parsing of functions and methods.
1443 impl<'a> Parser<'a> {
1444 /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
1448 attrs: &mut Vec<Attribute>,
1450 ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<Block>>)> {
1451 let header = self.parse_fn_front_matter()?; // `const ... fn`
1452 let ident = self.parse_ident()?; // `foo`
1453 let mut generics = self.parse_generics()?; // `<'a, T, ...>`
1454 let decl = self.parse_fn_decl(req_name, AllowPlus::Yes)?; // `(p: u8, ...)`
1455 generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
1456 let body = self.parse_fn_body(at_end, attrs)?; // `;` or `{ ... }`.
1457 Ok((ident, FnSig { header, decl }, generics, body))
1460 /// Parse the "body" of a function.
1461 /// This can either be `;` when there's no body,
1462 /// or e.g. a block when the function is a provided one.
1466 attrs: &mut Vec<Attribute>,
1467 ) -> PResult<'a, Option<P<Block>>> {
1468 let (inner_attrs, body) = match self.token.kind {
1473 token::OpenDelim(token::Brace) => {
1474 let (attrs, body) = self.parse_inner_attrs_and_block()?;
1477 token::Interpolated(ref nt) => match **nt {
1478 token::NtBlock(..) => {
1479 let (attrs, body) = self.parse_inner_attrs_and_block()?;
1482 _ => return self.expected_semi_or_open_brace(),
1484 _ => return self.expected_semi_or_open_brace(),
1486 attrs.extend(inner_attrs);
1491 /// Is the current token the start of an `FnHeader` / not a valid parse?
1492 fn check_fn_front_matter(&mut self) -> bool {
1493 // We use an over-approximation here.
1494 // `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
1495 const QUALS: [Symbol; 4] = [kw::Const, kw::Async, kw::Unsafe, kw::Extern];
1496 self.check_keyword(kw::Fn) // Definitely an `fn`.
1497 // `$qual fn` or `$qual $qual`:
1498 || QUALS.iter().any(|&kw| self.check_keyword(kw))
1499 && self.look_ahead(1, |t| {
1500 // ...qualified and then `fn`, e.g. `const fn`.
1501 t.is_keyword(kw::Fn)
1502 // Two qualifiers. This is enough. Due `async` we need to check that it's reserved.
1503 || t.is_non_raw_ident_where(|i| QUALS.contains(&i.name) && i.is_reserved())
1506 || self.check_keyword(kw::Extern)
1507 && self.look_ahead(1, |t| t.can_begin_literal_or_bool())
1508 && self.look_ahead(2, |t| t.is_keyword(kw::Fn))
1511 /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration,
1512 /// up to and including the `fn` keyword. The formal grammar is:
1515 /// Extern = "extern" StringLit ;
1516 /// FnQual = "const"? "async"? "unsafe"? Extern? ;
1517 /// FnFrontMatter = FnQual? "fn" ;
1519 fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
1520 let constness = self.parse_constness();
1521 let asyncness = self.parse_asyncness();
1522 let unsafety = self.parse_unsafety();
1523 let ext = self.parse_extern()?;
1525 if let Async::Yes { span, .. } = asyncness {
1526 self.ban_async_in_2015(span);
1529 if !self.eat_keyword(kw::Fn) {
1530 // It is possible for `expect_one_of` to recover given the contents of
1531 // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
1532 // account for this.
1533 if !self.expect_one_of(&[], &[])? {
1538 Ok(FnHeader { constness, unsafety, asyncness, ext })
1541 /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
1542 fn ban_async_in_2015(&self, span: Span) {
1543 if span.rust_2015() {
1544 let diag = self.diagnostic();
1545 struct_span_err!(diag, span, E0670, "`async fn` is not permitted in the 2015 edition")
1546 .note("to use `async fn`, switch to Rust 2018")
1547 .help("set `edition = \"2018\"` in `Cargo.toml`")
1548 .note("for more on editions, read https://doc.rust-lang.org/edition-guide")
1553 /// Parses the parameter list and result type of a function declaration.
1554 pub(super) fn parse_fn_decl(
1557 ret_allow_plus: AllowPlus,
1558 ) -> PResult<'a, P<FnDecl>> {
1560 inputs: self.parse_fn_params(req_name)?,
1561 output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes)?,
1565 /// Parses the parameter list of a function, including the `(` and `)` delimiters.
1566 fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, Vec<Param>> {
1567 let mut first_param = true;
1568 // Parse the arguments, starting out with `self` being allowed...
1569 let (mut params, _) = self.parse_paren_comma_seq(|p| {
1570 let param = p.parse_param_general(req_name, first_param).or_else(|mut e| {
1572 let lo = p.prev_span;
1573 // Skip every token until next possible arg or end.
1574 p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
1575 // Create a placeholder argument for proper arg count (issue #34264).
1576 Ok(dummy_arg(Ident::new(kw::Invalid, lo.to(p.prev_span))))
1578 // ...now that we've parsed the first argument, `self` is no longer allowed.
1579 first_param = false;
1582 // Replace duplicated recovered params with `_` pattern to avoid unnecessary errors.
1583 self.deduplicate_recovered_params_names(&mut params);
1587 /// Parses a single function parameter.
1589 /// - `self` is syntactically allowed when `first_param` holds.
1590 fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResult<'a, Param> {
1591 let lo = self.token.span;
1592 let attrs = self.parse_outer_attributes()?;
1594 // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
1595 if let Some(mut param) = self.parse_self_param()? {
1596 param.attrs = attrs.into();
1597 return if first_param { Ok(param) } else { self.recover_bad_self_param(param) };
1600 let is_name_required = match self.token.kind {
1601 token::DotDotDot => false,
1602 _ => req_name(&self.token),
1604 let (pat, ty) = if is_name_required || self.is_named_param() {
1605 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
1607 let pat = self.parse_fn_param_pat()?;
1608 if let Err(mut err) = self.expect(&token::Colon) {
1609 return if let Some(ident) =
1610 self.parameter_without_type(&mut err, pat, is_name_required, first_param)
1613 Ok(dummy_arg(ident))
1619 self.eat_incorrect_doc_comment_for_param_type();
1620 (pat, self.parse_ty_for_param()?)
1622 debug!("parse_param_general ident_to_pat");
1623 let parser_snapshot_before_ty = self.clone();
1624 self.eat_incorrect_doc_comment_for_param_type();
1625 let mut ty = self.parse_ty_for_param();
1627 && self.token != token::Comma
1628 && self.token != token::CloseDelim(token::Paren)
1630 // This wasn't actually a type, but a pattern looking like a type,
1631 // so we are going to rollback and re-parse for recovery.
1632 ty = self.unexpected();
1636 let ident = Ident::new(kw::Invalid, self.prev_span);
1637 let bm = BindingMode::ByValue(Mutability::Not);
1638 let pat = self.mk_pat_ident(ty.span, bm, ident);
1641 // If this is a C-variadic argument and we hit an error, return the error.
1642 Err(err) if self.token == token::DotDotDot => return Err(err),
1643 // Recover from attempting to parse the argument as a type without pattern.
1646 mem::replace(self, parser_snapshot_before_ty);
1647 self.recover_arg_parse()?
1652 let span = lo.to(self.token.span);
1655 attrs: attrs.into(),
1656 id: ast::DUMMY_NODE_ID,
1657 is_placeholder: false,
1664 /// Returns the parsed optional self parameter and whether a self shortcut was used.
1665 fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
1666 // Extract an identifier *after* having confirmed that the token is one.
1667 let expect_self_ident = |this: &mut Self| {
1668 match this.token.kind {
1669 // Preserve hygienic context.
1670 token::Ident(name, _) => {
1671 let span = this.token.span;
1673 Ident::new(name, span)
1675 _ => unreachable!(),
1678 // Is `self` `n` tokens ahead?
1679 let is_isolated_self = |this: &Self, n| {
1680 this.is_keyword_ahead(n, &[kw::SelfLower])
1681 && this.look_ahead(n + 1, |t| t != &token::ModSep)
1683 // Is `mut self` `n` tokens ahead?
1684 let is_isolated_mut_self =
1685 |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
1686 // Parse `self` or `self: TYPE`. We already know the current token is `self`.
1687 let parse_self_possibly_typed = |this: &mut Self, m| {
1688 let eself_ident = expect_self_ident(this);
1689 let eself_hi = this.prev_span;
1690 let eself = if this.eat(&token::Colon) {
1691 SelfKind::Explicit(this.parse_ty()?, m)
1695 Ok((eself, eself_ident, eself_hi))
1697 // Recover for the grammar `*self`, `*const self`, and `*mut self`.
1698 let recover_self_ptr = |this: &mut Self| {
1699 let msg = "cannot pass `self` by raw pointer";
1700 let span = this.token.span;
1701 this.struct_span_err(span, msg).span_label(span, msg).emit();
1703 Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_span))
1706 // Parse optional `self` parameter of a method.
1707 // Only a limited set of initial token sequences is considered `self` parameters; anything
1708 // else is parsed as a normal function parameter list, so some lookahead is required.
1709 let eself_lo = self.token.span;
1710 let (eself, eself_ident, eself_hi) = match self.token.kind {
1711 token::BinOp(token::And) => {
1712 let eself = if is_isolated_self(self, 1) {
1715 SelfKind::Region(None, Mutability::Not)
1716 } else if is_isolated_mut_self(self, 1) {
1720 SelfKind::Region(None, Mutability::Mut)
1721 } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
1724 let lt = self.expect_lifetime();
1725 SelfKind::Region(Some(lt), Mutability::Not)
1726 } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
1729 let lt = self.expect_lifetime();
1731 SelfKind::Region(Some(lt), Mutability::Mut)
1736 (eself, expect_self_ident(self), self.prev_span)
1739 token::BinOp(token::Star) if is_isolated_self(self, 1) => {
1741 recover_self_ptr(self)?
1743 // `*mut self` and `*const self`
1744 token::BinOp(token::Star)
1745 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
1749 recover_self_ptr(self)?
1751 // `self` and `self: TYPE`
1752 token::Ident(..) if is_isolated_self(self, 0) => {
1753 parse_self_possibly_typed(self, Mutability::Not)?
1755 // `mut self` and `mut self: TYPE`
1756 token::Ident(..) if is_isolated_mut_self(self, 0) => {
1758 parse_self_possibly_typed(self, Mutability::Mut)?
1760 _ => return Ok(None),
1763 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
1764 Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
1767 fn is_named_param(&self) -> bool {
1768 let offset = match self.token.kind {
1769 token::Interpolated(ref nt) => match **nt {
1770 token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
1773 token::BinOp(token::And) | token::AndAnd => 1,
1774 _ if self.token.is_keyword(kw::Mut) => 1,
1778 self.look_ahead(offset, |t| t.is_ident())
1779 && self.look_ahead(offset + 1, |t| t == &token::Colon)
1782 fn recover_first_param(&mut self) -> &'static str {
1784 .parse_outer_attributes()
1785 .and_then(|_| self.parse_self_param())
1786 .map_err(|mut e| e.cancel())
1788 Ok(Some(_)) => "method",