1 use super::{Parser, PResult, PathStyle, SemiColonMode, BlockMode};
3 use crate::maybe_whole;
6 self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle,
7 Item, ItemKind, ImplItem, TraitItem, TraitItemKind,
8 UseTree, UseTreeKind, PathSegment,
9 IsAuto, Constness, IsAsync, Unsafety, Defaultness,
10 Visibility, VisibilityKind, Mutability, FnDecl, FnHeader,
11 ForeignItem, ForeignItemKind,
12 Ty, TyKind, Generics, GenericBounds, TraitRef,
13 EnumDef, VariantData, StructField, AnonConst,
16 use crate::ext::base::DummyResult;
17 use crate::parse::token;
18 use crate::parse::parser::maybe_append;
19 use crate::parse::diagnostics::Error;
20 use crate::tokenstream::{TokenTree, TokenStream};
21 use crate::source_map::{respan, Span, Spanned};
22 use crate::symbol::{kw, sym};
26 use rustc_target::spec::abi::Abi;
27 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
29 /// Whether the type alias or associated type is a concrete type or an opaque type.
32 /// Just a new name for the same type.
34 /// Only trait impls of the type will be usable, not the actual type itself.
35 OpaqueTy(GenericBounds),
38 pub(super) type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>);
41 pub fn parse_item(&mut self) -> PResult<'a, Option<P<Item>>> {
42 let attrs = self.parse_outer_attributes()?;
43 self.parse_item_(attrs, true, false)
46 pub(super) fn parse_item_(
48 attrs: Vec<Attribute>,
50 attributes_allowed: bool,
51 ) -> PResult<'a, Option<P<Item>>> {
52 let mut unclosed_delims = vec![];
53 let (ret, tokens) = self.collect_tokens(|this| {
54 let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed);
55 unclosed_delims.append(&mut this.unclosed_delims);
58 self.unclosed_delims.append(&mut unclosed_delims);
60 // Once we've parsed an item and recorded the tokens we got while
61 // parsing we may want to store `tokens` into the item we're about to
62 // return. Note, though, that we specifically didn't capture tokens
63 // related to outer attributes. The `tokens` field here may later be
64 // used with procedural macros to convert this item back into a token
65 // stream, but during expansion we may be removing attributes as we go
68 // If we've got inner attributes then the `tokens` we've got above holds
69 // these inner attributes. If an inner attribute is expanded we won't
70 // actually remove it from the token stream, so we'll just keep yielding
71 // it (bad!). To work around this case for now we just avoid recording
72 // `tokens` if we detect any inner attributes. This should help keep
73 // expansion correct, but we should fix this bug one day!
76 if !i.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
77 i.tokens = Some(tokens);
84 /// Parses one of the items allowed by the flags.
85 fn parse_item_implementation(
87 attrs: Vec<Attribute>,
89 attributes_allowed: bool,
90 ) -> PResult<'a, Option<P<Item>>> {
91 maybe_whole!(self, NtItem, |item| {
92 let mut item = item.into_inner();
93 let mut attrs = attrs;
94 mem::swap(&mut item.attrs, &mut attrs);
95 item.attrs.extend(attrs);
99 let lo = self.token.span;
101 let visibility = self.parse_visibility(false)?;
103 if self.eat_keyword(kw::Use) {
105 let item_ = ItemKind::Use(P(self.parse_use_tree()?));
106 self.expect(&token::Semi)?;
108 let span = lo.to(self.prev_span);
110 self.mk_item(span, Ident::invalid(), item_, visibility, attrs);
111 return Ok(Some(item));
114 if self.eat_keyword(kw::Extern) {
115 let extern_sp = self.prev_span;
116 if self.eat_keyword(kw::Crate) {
117 return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?));
120 let opt_abi = self.parse_opt_abi()?;
122 if self.eat_keyword(kw::Fn) {
123 // EXTERN FUNCTION ITEM
124 let fn_span = self.prev_span;
125 let abi = opt_abi.unwrap_or(Abi::C);
126 let (ident, item_, extra_attrs) =
127 self.parse_item_fn(Unsafety::Normal,
128 respan(fn_span, IsAsync::NotAsync),
129 respan(fn_span, Constness::NotConst),
131 let prev_span = self.prev_span;
132 let item = self.mk_item(lo.to(prev_span),
136 maybe_append(attrs, extra_attrs));
137 return Ok(Some(item));
138 } else if self.check(&token::OpenDelim(token::Brace)) {
140 self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs, extern_sp)?,
147 if self.is_static_global() {
150 let m = self.parse_mutability();
151 let (ident, item_, extra_attrs) = self.parse_item_const(Some(m))?;
152 let prev_span = self.prev_span;
153 let item = self.mk_item(lo.to(prev_span),
157 maybe_append(attrs, extra_attrs));
158 return Ok(Some(item));
160 if self.eat_keyword(kw::Const) {
161 let const_span = self.prev_span;
162 if self.check_keyword(kw::Fn)
163 || (self.check_keyword(kw::Unsafe)
164 && self.is_keyword_ahead(1, &[kw::Fn])) {
165 // CONST FUNCTION ITEM
166 let unsafety = self.parse_unsafety();
168 let (ident, item_, extra_attrs) =
169 self.parse_item_fn(unsafety,
170 respan(const_span, IsAsync::NotAsync),
171 respan(const_span, Constness::Const),
173 let prev_span = self.prev_span;
174 let item = self.mk_item(lo.to(prev_span),
178 maybe_append(attrs, extra_attrs));
179 return Ok(Some(item));
183 if self.eat_keyword(kw::Mut) {
184 let prev_span = self.prev_span;
185 self.struct_span_err(prev_span, "const globals cannot be mutable")
186 .span_label(prev_span, "cannot be mutable")
189 "you might want to declare a static instead",
191 Applicability::MaybeIncorrect,
195 let (ident, item_, extra_attrs) = self.parse_item_const(None)?;
196 let prev_span = self.prev_span;
197 let item = self.mk_item(lo.to(prev_span),
201 maybe_append(attrs, extra_attrs));
202 return Ok(Some(item));
205 // Parses `async unsafe? fn`.
206 if self.check_keyword(kw::Async) {
207 let async_span = self.token.span;
208 if self.is_keyword_ahead(1, &[kw::Fn])
209 || self.is_keyword_ahead(2, &[kw::Fn])
211 // ASYNC FUNCTION ITEM
212 self.bump(); // `async`
213 let unsafety = self.parse_unsafety(); // `unsafe`?
214 self.expect_keyword(kw::Fn)?; // `fn`
215 let fn_span = self.prev_span;
216 let (ident, item_, extra_attrs) =
217 self.parse_item_fn(unsafety,
218 respan(async_span, IsAsync::Async {
219 closure_id: DUMMY_NODE_ID,
220 return_impl_trait_id: DUMMY_NODE_ID,
222 respan(fn_span, Constness::NotConst),
224 let prev_span = self.prev_span;
225 let item = self.mk_item(lo.to(prev_span),
229 maybe_append(attrs, extra_attrs));
230 self.ban_async_in_2015(async_span);
231 return Ok(Some(item));
234 if self.check_keyword(kw::Unsafe) &&
235 self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
238 self.bump(); // `unsafe`
239 let is_auto = if self.eat_keyword(kw::Trait) {
242 self.expect_keyword(kw::Auto)?;
243 self.expect_keyword(kw::Trait)?;
246 let (ident, item_, extra_attrs) =
247 self.parse_item_trait(is_auto, Unsafety::Unsafe)?;
248 let prev_span = self.prev_span;
249 let item = self.mk_item(lo.to(prev_span),
253 maybe_append(attrs, extra_attrs));
254 return Ok(Some(item));
256 if self.check_keyword(kw::Impl) ||
257 self.check_keyword(kw::Unsafe) &&
258 self.is_keyword_ahead(1, &[kw::Impl]) ||
259 self.check_keyword(kw::Default) &&
260 self.is_keyword_ahead(1, &[kw::Impl, kw::Unsafe]) {
262 let defaultness = self.parse_defaultness();
263 let unsafety = self.parse_unsafety();
264 self.expect_keyword(kw::Impl)?;
265 let (ident, item, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?;
266 let span = lo.to(self.prev_span);
267 return Ok(Some(self.mk_item(span, ident, item, visibility,
268 maybe_append(attrs, extra_attrs))));
270 if self.check_keyword(kw::Fn) {
273 let fn_span = self.prev_span;
274 let (ident, item_, extra_attrs) =
275 self.parse_item_fn(Unsafety::Normal,
276 respan(fn_span, IsAsync::NotAsync),
277 respan(fn_span, Constness::NotConst),
279 let prev_span = self.prev_span;
280 let item = self.mk_item(lo.to(prev_span),
284 maybe_append(attrs, extra_attrs));
285 return Ok(Some(item));
287 if self.check_keyword(kw::Unsafe)
288 && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
289 // UNSAFE FUNCTION ITEM
290 self.bump(); // `unsafe`
291 // `{` is also expected after `unsafe`; in case of error, include it in the diagnostic.
292 self.check(&token::OpenDelim(token::Brace));
293 let abi = if self.eat_keyword(kw::Extern) {
294 self.parse_opt_abi()?.unwrap_or(Abi::C)
298 self.expect_keyword(kw::Fn)?;
299 let fn_span = self.prev_span;
300 let (ident, item_, extra_attrs) =
301 self.parse_item_fn(Unsafety::Unsafe,
302 respan(fn_span, IsAsync::NotAsync),
303 respan(fn_span, Constness::NotConst),
305 let prev_span = self.prev_span;
306 let item = self.mk_item(lo.to(prev_span),
310 maybe_append(attrs, extra_attrs));
311 return Ok(Some(item));
313 if self.eat_keyword(kw::Mod) {
315 let (ident, item_, extra_attrs) =
316 self.parse_item_mod(&attrs[..])?;
317 let prev_span = self.prev_span;
318 let item = self.mk_item(lo.to(prev_span),
322 maybe_append(attrs, extra_attrs));
323 return Ok(Some(item));
325 if let Some(type_) = self.eat_type() {
326 let (ident, alias, generics) = type_?;
328 let item_ = match alias {
329 AliasKind::Weak(ty) => ItemKind::TyAlias(ty, generics),
330 AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics),
332 let prev_span = self.prev_span;
333 let item = self.mk_item(lo.to(prev_span),
338 return Ok(Some(item));
340 if self.eat_keyword(kw::Enum) {
342 let (ident, item_, extra_attrs) = self.parse_item_enum()?;
343 let prev_span = self.prev_span;
344 let item = self.mk_item(lo.to(prev_span),
348 maybe_append(attrs, extra_attrs));
349 return Ok(Some(item));
351 if self.check_keyword(kw::Trait)
352 || (self.check_keyword(kw::Auto)
353 && self.is_keyword_ahead(1, &[kw::Trait]))
355 let is_auto = if self.eat_keyword(kw::Trait) {
358 self.expect_keyword(kw::Auto)?;
359 self.expect_keyword(kw::Trait)?;
363 let (ident, item_, extra_attrs) =
364 self.parse_item_trait(is_auto, Unsafety::Normal)?;
365 let prev_span = self.prev_span;
366 let item = self.mk_item(lo.to(prev_span),
370 maybe_append(attrs, extra_attrs));
371 return Ok(Some(item));
373 if self.eat_keyword(kw::Struct) {
375 let (ident, item_, extra_attrs) = self.parse_item_struct()?;
376 let prev_span = self.prev_span;
377 let item = self.mk_item(lo.to(prev_span),
381 maybe_append(attrs, extra_attrs));
382 return Ok(Some(item));
384 if self.is_union_item() {
387 let (ident, item_, extra_attrs) = self.parse_item_union()?;
388 let prev_span = self.prev_span;
389 let item = self.mk_item(lo.to(prev_span),
393 maybe_append(attrs, extra_attrs));
394 return Ok(Some(item));
396 if let Some(macro_def) = self.eat_macro_def(&attrs, &visibility, lo)? {
397 return Ok(Some(macro_def));
400 // Verify whether we have encountered a struct or method definition where the user forgot to
401 // add the `struct` or `fn` keyword after writing `pub`: `pub S {}`
402 if visibility.node.is_pub() &&
403 self.check_ident() &&
404 self.look_ahead(1, |t| *t != token::Not)
406 // Space between `pub` keyword and the identifier
409 // ^^^ `sp` points here
410 let sp = self.prev_span.between(self.token.span);
411 let full_sp = self.prev_span.to(self.token.span);
412 let ident_sp = self.token.span;
413 if self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) {
414 // possible public struct definition where `struct` was forgotten
415 let ident = self.parse_ident().unwrap();
416 let msg = format!("add `struct` here to parse `{}` as a public struct",
418 let mut err = self.diagnostic()
419 .struct_span_err(sp, "missing `struct` for struct definition");
420 err.span_suggestion_short(
421 sp, &msg, " struct ".into(), Applicability::MaybeIncorrect // speculative
424 } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
425 let ident = self.parse_ident().unwrap();
427 let kw_name = if let Ok(Some(_)) = self.parse_self_parameter_with_attrs()
428 .map_err(|mut e| e.cancel())
434 self.consume_block(token::Paren);
435 let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
436 self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
438 ("fn", kw_name, false)
439 } else if self.check(&token::OpenDelim(token::Brace)) {
441 ("fn", kw_name, false)
442 } else if self.check(&token::Colon) {
446 ("fn` or `struct", "function or struct", true)
449 let msg = format!("missing `{}` for {} definition", kw, kw_name);
450 let mut err = self.diagnostic().struct_span_err(sp, &msg);
452 self.consume_block(token::Brace);
453 let suggestion = format!("add `{}` here to parse `{}` as a public {}",
457 err.span_suggestion_short(
458 sp, &suggestion, format!(" {} ", kw), Applicability::MachineApplicable
461 if let Ok(snippet) = self.span_to_snippet(ident_sp) {
464 "if you meant to call a macro, try",
465 format!("{}!", snippet),
466 // this is the `ambiguous` conditional branch
467 Applicability::MaybeIncorrect
470 err.help("if you meant to call a macro, remove the `pub` \
471 and add a trailing `!` after the identifier");
475 } else if self.look_ahead(1, |t| *t == token::Lt) {
476 let ident = self.parse_ident().unwrap();
477 self.eat_to_tokens(&[&token::Gt]);
479 let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
480 if let Ok(Some(_)) = self.parse_self_parameter_with_attrs()
481 .map_err(|mut e| e.cancel())
483 ("fn", "method", false)
485 ("fn", "function", false)
487 } else if self.check(&token::OpenDelim(token::Brace)) {
488 ("struct", "struct", false)
490 ("fn` or `struct", "function or struct", true)
492 let msg = format!("missing `{}` for {} definition", kw, kw_name);
493 let mut err = self.diagnostic().struct_span_err(sp, &msg);
495 err.span_suggestion_short(
497 &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
499 Applicability::MachineApplicable,
505 self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
508 /// This is the fall-through for parsing items.
509 fn parse_macro_use_or_failure(
511 attrs: Vec<Attribute> ,
512 macros_allowed: bool,
513 attributes_allowed: bool,
515 visibility: Visibility
516 ) -> PResult<'a, Option<P<Item>>> {
517 if macros_allowed && self.token.is_path_start() &&
518 !(self.is_async_fn() && self.token.span.rust_2015()) {
519 // MACRO INVOCATION ITEM
521 let prev_span = self.prev_span;
522 self.complain_if_pub_macro(&visibility.node, prev_span);
524 let mac_lo = self.token.span;
527 let path = self.parse_path(PathStyle::Mod)?;
528 self.expect(&token::Not)?;
529 let (delim, tts) = self.expect_delimited_token_tree()?;
530 if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
531 self.report_invalid_macro_expansion_item();
534 let hi = self.prev_span;
540 prior_type_ascription: self.last_type_ascription,
543 self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs);
544 return Ok(Some(item));
547 // FAILURE TO PARSE ITEM
548 match visibility.node {
549 VisibilityKind::Inherited => {}
551 return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`"));
555 if !attributes_allowed && !attrs.is_empty() {
556 self.expected_item_err(&attrs)?;
561 /// Emits an expected-item-after-attributes error.
562 fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
563 let message = match attrs.last() {
564 Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
565 _ => "expected item after attributes",
568 let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
569 if attrs.last().unwrap().is_sugared_doc {
570 err.span_label(self.prev_span, "this doc comment doesn't document anything");
575 pub(super) fn is_async_fn(&self) -> bool {
576 self.token.is_keyword(kw::Async) &&
577 self.is_keyword_ahead(1, &[kw::Fn])
580 /// Parses a macro invocation inside a `trait`, `impl` or `extern` block.
581 fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
582 at_end: &mut bool) -> PResult<'a, Option<Mac>>
584 if self.token.is_path_start() &&
585 !(self.is_async_fn() && self.token.span.rust_2015()) {
586 let prev_span = self.prev_span;
587 let lo = self.token.span;
588 let path = self.parse_path(PathStyle::Mod)?;
590 if path.segments.len() == 1 {
591 if !self.eat(&token::Not) {
592 return Err(self.missing_assoc_item_kind_err(item_kind, prev_span));
595 self.expect(&token::Not)?;
598 if let Some(vis) = vis {
599 self.complain_if_pub_macro(&vis.node, prev_span);
604 // eat a matched-delimiter token tree:
605 let (delim, tts) = self.expect_delimited_token_tree()?;
606 if delim != MacDelimiter::Brace {
607 self.expect(&token::Semi)?;
614 span: lo.to(self.prev_span),
615 prior_type_ascription: self.last_type_ascription,
622 fn missing_assoc_item_kind_err(&self, item_type: &str, prev_span: Span)
623 -> DiagnosticBuilder<'a>
625 let expected_kinds = if item_type == "extern" {
626 "missing `fn`, `type`, or `static`"
628 "missing `fn`, `type`, or `const`"
631 // Given this code `path(`, it seems like this is not
632 // setting the visibility of a macro invocation, but rather
633 // a mistyped method declaration.
634 // Create a diagnostic pointing out that `fn` is missing.
636 // x | pub path(&self) {
637 // | ^ missing `fn`, `type`, or `const`
639 // ^^ `sp` below will point to this
640 let sp = prev_span.between(self.prev_span);
641 let mut err = self.diagnostic().struct_span_err(
643 &format!("{} for {}-item declaration",
644 expected_kinds, item_type));
645 err.span_label(sp, expected_kinds);
649 /// Parses an implementation item, `impl` keyword is already parsed.
651 /// impl<'a, T> TYPE { /* impl items */ }
652 /// impl<'a, T> TRAIT for TYPE { /* impl items */ }
653 /// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
655 /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
656 /// `impl` GENERICS `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}`
657 /// `impl` GENERICS `!`? TYPE (`where` PREDICATES)? `{` BODY `}`
658 fn parse_item_impl(&mut self, unsafety: Unsafety, defaultness: Defaultness)
659 -> PResult<'a, ItemInfo> {
660 // First, parse generic parameters if necessary.
661 let mut generics = if self.choose_generics_over_qpath() {
662 self.parse_generics()?
667 // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
668 let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
670 ast::ImplPolarity::Negative
672 ast::ImplPolarity::Positive
675 // Parse both types and traits as a type, then reinterpret if necessary.
676 let err_path = |span| ast::Path::from_ident(Ident::new(kw::Invalid, span));
677 let ty_first = if self.token.is_keyword(kw::For) &&
678 self.look_ahead(1, |t| t != &token::Lt) {
679 let span = self.prev_span.between(self.token.span);
680 self.struct_span_err(span, "missing trait in a trait impl").emit();
681 P(Ty { node: TyKind::Path(None, err_path(span)), span, id: DUMMY_NODE_ID })
686 // If `for` is missing we try to recover.
687 let has_for = self.eat_keyword(kw::For);
688 let missing_for_span = self.prev_span.between(self.token.span);
690 let ty_second = if self.token == token::DotDot {
691 // We need to report this error after `cfg` expansion for compatibility reasons
692 self.bump(); // `..`, do not add it to expected tokens
693 Some(DummyResult::raw_ty(self.prev_span, true))
694 } else if has_for || self.token.can_begin_type() {
695 Some(self.parse_ty()?)
700 generics.where_clause = self.parse_where_clause()?;
702 let (impl_items, attrs) = self.parse_impl_body()?;
704 let item_kind = match ty_second {
706 // impl Trait for Type
708 self.struct_span_err(missing_for_span, "missing `for` in a trait impl")
709 .span_suggestion_short(
713 Applicability::MachineApplicable,
717 let ty_first = ty_first.into_inner();
718 let path = match ty_first.node {
719 // This notably includes paths passed through `ty` macro fragments (#46438).
720 TyKind::Path(None, path) => path,
722 self.span_err(ty_first.span, "expected a trait, found type");
723 err_path(ty_first.span)
726 let trait_ref = TraitRef { path, ref_id: ty_first.id };
728 ItemKind::Impl(unsafety, polarity, defaultness,
729 generics, Some(trait_ref), ty_second, impl_items)
733 ItemKind::Impl(unsafety, polarity, defaultness,
734 generics, None, ty_first, impl_items)
738 Ok((Ident::invalid(), item_kind, Some(attrs)))
741 fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
742 self.expect(&token::OpenDelim(token::Brace))?;
743 let attrs = self.parse_inner_attributes()?;
745 let mut impl_items = Vec::new();
746 while !self.eat(&token::CloseDelim(token::Brace)) {
747 let mut at_end = false;
748 match self.parse_impl_item(&mut at_end) {
749 Ok(impl_item) => impl_items.push(impl_item),
753 self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
758 Ok((impl_items, attrs))
761 /// Parses an impl item.
762 pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
763 maybe_whole!(self, NtImplItem, |x| x);
764 let attrs = self.parse_outer_attributes()?;
765 let mut unclosed_delims = vec![];
766 let (mut item, tokens) = self.collect_tokens(|this| {
767 let item = this.parse_impl_item_(at_end, attrs);
768 unclosed_delims.append(&mut this.unclosed_delims);
771 self.unclosed_delims.append(&mut unclosed_delims);
773 // See `parse_item` for why this clause is here.
774 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
775 item.tokens = Some(tokens);
780 fn parse_impl_item_(&mut self,
782 mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> {
783 let lo = self.token.span;
784 let vis = self.parse_visibility(false)?;
785 let defaultness = self.parse_defaultness();
786 let (name, node, generics) = if let Some(type_) = self.eat_type() {
787 let (name, alias, generics) = type_?;
788 let kind = match alias {
789 AliasKind::Weak(typ) => ast::ImplItemKind::TyAlias(typ),
790 AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
792 (name, kind, generics)
793 } else if self.is_const_item() {
794 // This parses the grammar:
795 // ImplItemConst = "const" Ident ":" Ty "=" Expr ";"
796 self.expect_keyword(kw::Const)?;
797 let name = self.parse_ident()?;
798 self.expect(&token::Colon)?;
799 let typ = self.parse_ty()?;
800 self.expect(&token::Eq)?;
801 let expr = self.parse_expr()?;
802 self.expect(&token::Semi)?;
803 (name, ast::ImplItemKind::Const(typ, expr), Generics::default())
805 let (name, inner_attrs, generics, node) = self.parse_impl_method(&vis, at_end)?;
806 attrs.extend(inner_attrs);
807 (name, node, generics)
812 span: lo.to(self.prev_span),
823 /// Parses defaultness (i.e., `default` or nothing).
824 fn parse_defaultness(&mut self) -> Defaultness {
825 // `pub` is included for better error messages
826 if self.check_keyword(kw::Default) &&
827 self.is_keyword_ahead(1, &[
838 self.bump(); // `default`
845 /// Returns `true` if we are looking at `const ID`
846 /// (returns `false` for things like `const fn`, etc.).
847 fn is_const_item(&self) -> bool {
848 self.token.is_keyword(kw::Const) &&
849 !self.is_keyword_ahead(1, &[kw::Fn, kw::Unsafe])
852 /// Parses a method or a macro invocation in a trait impl.
853 fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
854 -> PResult<'a, (Ident, Vec<Attribute>, Generics, ast::ImplItemKind)> {
855 // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
856 if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
858 Ok((Ident::invalid(), vec![], Generics::default(),
859 ast::ImplItemKind::Macro(mac)))
861 let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
862 let ident = self.parse_ident()?;
863 let mut generics = self.parse_generics()?;
864 let decl = self.parse_fn_decl_with_self(|p| {
865 p.parse_param_general(true, false, |_| true)
867 generics.where_clause = self.parse_where_clause()?;
869 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
870 let header = ast::FnHeader { abi, unsafety, constness, asyncness };
871 Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(
872 ast::MethodSig { header, decl },
878 /// Parses all the "front matter" for a `fn` declaration, up to
879 /// and including the `fn` keyword:
883 /// - `const unsafe fn`
886 fn parse_fn_front_matter(&mut self)
894 let is_const_fn = self.eat_keyword(kw::Const);
895 let const_span = self.prev_span;
896 let asyncness = self.parse_asyncness();
897 if let IsAsync::Async { .. } = asyncness {
898 self.ban_async_in_2015(self.prev_span);
900 let asyncness = respan(self.prev_span, asyncness);
901 let unsafety = self.parse_unsafety();
902 let (constness, unsafety, abi) = if is_const_fn {
903 (respan(const_span, Constness::Const), unsafety, Abi::Rust)
905 let abi = if self.eat_keyword(kw::Extern) {
906 self.parse_opt_abi()?.unwrap_or(Abi::C)
910 (respan(self.prev_span, Constness::NotConst), unsafety, abi)
912 if !self.eat_keyword(kw::Fn) {
913 // It is possible for `expect_one_of` to recover given the contents of
914 // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
916 if !self.expect_one_of(&[], &[])? { unreachable!() }
918 Ok((constness, unsafety, asyncness, abi))
921 /// Parses `trait Foo { ... }` or `trait Foo = Bar;`.
922 fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
923 let ident = self.parse_ident()?;
924 let mut tps = self.parse_generics()?;
926 // Parse optional colon and supertrait bounds.
927 let bounds = if self.eat(&token::Colon) {
928 self.parse_generic_bounds(Some(self.prev_span))?
933 if self.eat(&token::Eq) {
934 // It's a trait alias.
935 let bounds = self.parse_generic_bounds(None)?;
936 tps.where_clause = self.parse_where_clause()?;
937 self.expect(&token::Semi)?;
938 if is_auto == IsAuto::Yes {
939 let msg = "trait aliases cannot be `auto`";
940 self.struct_span_err(self.prev_span, msg)
941 .span_label(self.prev_span, msg)
944 if unsafety != Unsafety::Normal {
945 let msg = "trait aliases cannot be `unsafe`";
946 self.struct_span_err(self.prev_span, msg)
947 .span_label(self.prev_span, msg)
950 Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
952 // It's a normal trait.
953 tps.where_clause = self.parse_where_clause()?;
954 self.expect(&token::OpenDelim(token::Brace))?;
955 let mut trait_items = vec![];
956 while !self.eat(&token::CloseDelim(token::Brace)) {
957 if let token::DocComment(_) = self.token.kind {
958 if self.look_ahead(1,
959 |tok| tok == &token::CloseDelim(token::Brace)) {
960 self.diagnostic().struct_span_err_with_code(
962 "found a documentation comment that doesn't document anything",
963 DiagnosticId::Error("E0584".into()),
966 "doc comments must come before what they document, maybe a \
967 comment was intended with `//`?",
974 let mut at_end = false;
975 match self.parse_trait_item(&mut at_end) {
976 Ok(item) => trait_items.push(item),
980 self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
985 Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
989 /// Parses the items in a trait declaration.
990 pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
991 maybe_whole!(self, NtTraitItem, |x| x);
992 let attrs = self.parse_outer_attributes()?;
993 let mut unclosed_delims = vec![];
994 let (mut item, tokens) = self.collect_tokens(|this| {
995 let item = this.parse_trait_item_(at_end, attrs);
996 unclosed_delims.append(&mut this.unclosed_delims);
999 self.unclosed_delims.append(&mut unclosed_delims);
1000 // See `parse_item` for why this clause is here.
1001 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
1002 item.tokens = Some(tokens);
1007 fn parse_trait_item_(&mut self,
1009 mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
1010 let lo = self.token.span;
1012 let (name, node, generics) = if self.eat_keyword(kw::Type) {
1013 self.parse_trait_item_assoc_ty()?
1014 } else if self.is_const_item() {
1015 self.expect_keyword(kw::Const)?;
1016 let ident = self.parse_ident()?;
1017 self.expect(&token::Colon)?;
1018 let ty = self.parse_ty()?;
1019 let default = if self.eat(&token::Eq) {
1020 let expr = self.parse_expr()?;
1021 self.expect(&token::Semi)?;
1024 self.expect(&token::Semi)?;
1027 (ident, TraitItemKind::Const(ty, default), Generics::default())
1028 } else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
1029 // trait item macro.
1030 (Ident::invalid(), ast::TraitItemKind::Macro(mac), Generics::default())
1032 let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
1034 let ident = self.parse_ident()?;
1035 let mut generics = self.parse_generics()?;
1037 let decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
1038 // This is somewhat dubious; We don't want to allow
1039 // argument names to be left off if there is a
1042 // We don't allow argument names to be left off in edition 2018.
1043 let is_name_required = p.token.span.rust_2018();
1044 p.parse_param_general(true, false, |_| is_name_required)
1046 generics.where_clause = self.parse_where_clause()?;
1048 let sig = ast::MethodSig {
1058 let body = match self.token.kind {
1062 debug!("parse_trait_methods(): parsing required method");
1065 token::OpenDelim(token::Brace) => {
1066 debug!("parse_trait_methods(): parsing provided method");
1068 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1069 attrs.extend(inner_attrs.iter().cloned());
1072 token::Interpolated(ref nt) => {
1074 token::NtBlock(..) => {
1076 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1077 attrs.extend(inner_attrs.iter().cloned());
1081 return self.expected_semi_or_open_brace();
1086 return self.expected_semi_or_open_brace();
1089 (ident, ast::TraitItemKind::Method(sig, body), generics)
1098 span: lo.to(self.prev_span),
1103 /// Parses the following grammar:
1105 /// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
1106 fn parse_trait_item_assoc_ty(&mut self)
1107 -> PResult<'a, (Ident, TraitItemKind, Generics)> {
1108 let ident = self.parse_ident()?;
1109 let mut generics = self.parse_generics()?;
1111 // Parse optional colon and param bounds.
1112 let bounds = if self.eat(&token::Colon) {
1113 self.parse_generic_bounds(None)?
1117 generics.where_clause = self.parse_where_clause()?;
1119 let default = if self.eat(&token::Eq) {
1120 Some(self.parse_ty()?)
1124 self.expect(&token::Semi)?;
1126 Ok((ident, TraitItemKind::Type(bounds, default), generics))
1129 /// Parses a `UseTree`.
1132 /// USE_TREE = [`::`] `*` |
1133 /// [`::`] `{` USE_TREE_LIST `}` |
1135 /// PATH `::` `{` USE_TREE_LIST `}` |
1136 /// PATH [`as` IDENT]
1138 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
1139 let lo = self.token.span;
1141 let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
1142 let kind = if self.check(&token::OpenDelim(token::Brace)) ||
1143 self.check(&token::BinOp(token::Star)) ||
1144 self.is_import_coupler() {
1145 // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
1146 let mod_sep_ctxt = self.token.span.ctxt();
1147 if self.eat(&token::ModSep) {
1148 prefix.segments.push(
1149 PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))
1153 if self.eat(&token::BinOp(token::Star)) {
1156 UseTreeKind::Nested(self.parse_use_tree_list()?)
1159 // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
1160 prefix = self.parse_path(PathStyle::Mod)?;
1162 if self.eat(&token::ModSep) {
1163 if self.eat(&token::BinOp(token::Star)) {
1166 UseTreeKind::Nested(self.parse_use_tree_list()?)
1169 UseTreeKind::Simple(self.parse_rename()?, DUMMY_NODE_ID, DUMMY_NODE_ID)
1173 Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) })
1176 /// Parses a `UseTreeKind::Nested(list)`.
1179 /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
1181 fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
1182 self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, DUMMY_NODE_ID)))
1186 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
1187 if self.eat_keyword(kw::As) {
1188 self.parse_ident_or_underscore().map(Some)
1194 fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
1195 match self.token.kind {
1196 token::Ident(name, false) if name == kw::Underscore => {
1197 let span = self.token.span;
1199 Ok(Ident::new(name, span))
1201 _ => self.parse_ident(),
1205 /// Parses `extern crate` links.
1210 /// extern crate foo;
1211 /// extern crate bar as foo;
1213 fn parse_item_extern_crate(
1216 visibility: Visibility,
1217 attrs: Vec<Attribute>
1218 ) -> PResult<'a, P<Item>> {
1219 // Accept `extern crate name-like-this` for better diagnostics
1220 let orig_name = self.parse_crate_name_with_dashes()?;
1221 let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
1222 (rename, Some(orig_name.name))
1226 self.expect(&token::Semi)?;
1228 let span = lo.to(self.prev_span);
1229 Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs))
1232 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
1233 let error_msg = "crate name using dashes are not valid in `extern crate` statements";
1234 let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
1236 let mut ident = if self.token.is_keyword(kw::SelfLower) {
1237 self.parse_path_segment_ident()
1241 let mut idents = vec![];
1242 let mut replacement = vec![];
1243 let mut fixed_crate_name = false;
1244 // Accept `extern crate name-like-this` for better diagnostics.
1245 let dash = token::BinOp(token::BinOpToken::Minus);
1246 if self.token == dash { // Do not include `-` as part of the expected tokens list.
1247 while self.eat(&dash) {
1248 fixed_crate_name = true;
1249 replacement.push((self.prev_span, "_".to_string()));
1250 idents.push(self.parse_ident()?);
1253 if fixed_crate_name {
1254 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
1255 let mut fixed_name = format!("{}", ident.name);
1256 for part in idents {
1257 fixed_name.push_str(&format!("_{}", part.name));
1259 ident = Ident::from_str_and_span(&fixed_name, fixed_name_sp);
1261 self.struct_span_err(fixed_name_sp, error_msg)
1262 .span_label(fixed_name_sp, "dash-separated idents are not valid")
1263 .multipart_suggestion(suggestion_msg, replacement, Applicability::MachineApplicable)
1269 /// Parses an item-position function declaration.
1273 asyncness: Spanned<IsAsync>,
1274 constness: Spanned<Constness>,
1276 ) -> PResult<'a, ItemInfo> {
1277 let (ident, mut generics) = self.parse_fn_header()?;
1278 let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe;
1279 let decl = self.parse_fn_decl(allow_c_variadic)?;
1280 generics.where_clause = self.parse_where_clause()?;
1281 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1282 let header = FnHeader { unsafety, asyncness, constness, abi };
1283 Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
1286 /// Parses the name and optional generic types of a function header.
1287 fn parse_fn_header(&mut self) -> PResult<'a, (Ident, Generics)> {
1288 let id = self.parse_ident()?;
1289 let generics = self.parse_generics()?;
1293 /// Parses the argument list and result type of a function declaration.
1294 fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P<FnDecl>> {
1295 let (args, c_variadic) = self.parse_fn_params(true, allow_c_variadic)?;
1296 let ret_ty = self.parse_ret_ty(true)?;
1305 /// Parses `extern` for foreign ABIs modules.
1307 /// `extern` is expected to have been
1308 /// consumed before calling this method.
1312 /// ```ignore (only-for-syntax-highlight)
1316 fn parse_item_foreign_mod(
1319 opt_abi: Option<Abi>,
1320 visibility: Visibility,
1321 mut attrs: Vec<Attribute>,
1323 ) -> PResult<'a, P<Item>> {
1324 self.expect(&token::OpenDelim(token::Brace))?;
1326 let abi = opt_abi.unwrap_or(Abi::C);
1328 attrs.extend(self.parse_inner_attributes()?);
1330 let mut foreign_items = vec![];
1331 while !self.eat(&token::CloseDelim(token::Brace)) {
1332 foreign_items.push(self.parse_foreign_item(extern_sp)?);
1335 let prev_span = self.prev_span;
1336 let m = ast::ForeignMod {
1338 items: foreign_items
1340 let invalid = Ident::invalid();
1341 Ok(self.mk_item(lo.to(prev_span), invalid, ItemKind::ForeignMod(m), visibility, attrs))
1344 /// Parses a foreign item.
1345 crate fn parse_foreign_item(&mut self, extern_sp: Span) -> PResult<'a, ForeignItem> {
1346 maybe_whole!(self, NtForeignItem, |ni| ni);
1348 let attrs = self.parse_outer_attributes()?;
1349 let lo = self.token.span;
1350 let visibility = self.parse_visibility(false)?;
1352 // FOREIGN STATIC ITEM
1353 // Treat `const` as `static` for error recovery, but don't add it to expected tokens.
1354 if self.check_keyword(kw::Static) || self.token.is_keyword(kw::Const) {
1355 if self.token.is_keyword(kw::Const) {
1357 .struct_span_err(self.token.span, "extern items cannot be `const`")
1360 "try using a static value",
1361 "static".to_owned(),
1362 Applicability::MachineApplicable
1365 self.bump(); // `static` or `const`
1366 return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?);
1368 // FOREIGN FUNCTION ITEM
1369 if self.check_keyword(kw::Fn) {
1370 return Ok(self.parse_item_foreign_fn(visibility, lo, attrs, extern_sp)?);
1372 // FOREIGN TYPE ITEM
1373 if self.check_keyword(kw::Type) {
1374 return Ok(self.parse_item_foreign_type(visibility, lo, attrs)?);
1377 match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? {
1381 ident: Ident::invalid(),
1382 span: lo.to(self.prev_span),
1386 node: ForeignItemKind::Macro(mac),
1391 if !attrs.is_empty() {
1392 self.expected_item_err(&attrs)?;
1400 /// Parses a function declaration from a foreign module.
1401 fn parse_item_foreign_fn(
1403 vis: ast::Visibility,
1405 attrs: Vec<Attribute>,
1407 ) -> PResult<'a, ForeignItem> {
1408 self.expect_keyword(kw::Fn)?;
1410 let (ident, mut generics) = self.parse_fn_header()?;
1411 let decl = self.parse_fn_decl(true)?;
1412 generics.where_clause = self.parse_where_clause()?;
1413 let hi = self.token.span;
1414 self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
1415 Ok(ast::ForeignItem {
1418 node: ForeignItemKind::Fn(decl, generics),
1425 /// Parses a static item from a foreign module.
1426 /// Assumes that the `static` keyword is already parsed.
1427 fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
1428 -> PResult<'a, ForeignItem> {
1429 let mutbl = self.parse_mutability();
1430 let ident = self.parse_ident()?;
1431 self.expect(&token::Colon)?;
1432 let ty = self.parse_ty()?;
1433 let hi = self.token.span;
1434 self.expect(&token::Semi)?;
1438 node: ForeignItemKind::Static(ty, mutbl),
1445 /// Parses a type from a foreign module.
1446 fn parse_item_foreign_type(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
1447 -> PResult<'a, ForeignItem> {
1448 self.expect_keyword(kw::Type)?;
1450 let ident = self.parse_ident()?;
1451 let hi = self.token.span;
1452 self.expect(&token::Semi)?;
1453 Ok(ast::ForeignItem {
1456 node: ForeignItemKind::Ty,
1463 fn is_static_global(&mut self) -> bool {
1464 if self.check_keyword(kw::Static) {
1465 // Check if this could be a closure.
1466 !self.look_ahead(1, |token| {
1467 if token.is_keyword(kw::Move) {
1471 token::BinOp(token::Or) | token::OrOr => true,
1480 fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
1481 let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
1482 self.expect(&token::Colon)?;
1483 let ty = self.parse_ty()?;
1484 self.expect(&token::Eq)?;
1485 let e = self.parse_expr()?;
1486 self.expect(&token::Semi)?;
1487 let item = match m {
1488 Some(m) => ItemKind::Static(ty, m, e),
1489 None => ItemKind::Const(ty, e),
1491 Ok((id, item, None))
1494 /// Parses `type Foo = Bar;` or returns `None`
1495 /// without modifying the parser state.
1496 fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, Generics)>> {
1497 // This parses the grammar:
1498 // Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
1499 if self.eat_keyword(kw::Type) {
1500 Some(self.parse_type_alias())
1506 /// Parses a type alias or opaque type.
1507 fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, Generics)> {
1508 let ident = self.parse_ident()?;
1509 let mut tps = self.parse_generics()?;
1510 tps.where_clause = self.parse_where_clause()?;
1511 self.expect(&token::Eq)?;
1512 let alias = if self.check_keyword(kw::Impl) {
1514 let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
1515 AliasKind::OpaqueTy(bounds)
1517 let ty = self.parse_ty()?;
1520 self.expect(&token::Semi)?;
1521 Ok((ident, alias, tps))
1524 /// Parses an enum declaration.
1525 fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
1526 let id = self.parse_ident()?;
1527 let mut generics = self.parse_generics()?;
1528 generics.where_clause = self.parse_where_clause()?;
1529 self.expect(&token::OpenDelim(token::Brace))?;
1531 let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
1532 self.recover_stmt();
1533 self.eat(&token::CloseDelim(token::Brace));
1536 Ok((id, ItemKind::Enum(enum_definition, generics), None))
1539 /// Parses the part of an enum declaration following the `{`.
1540 fn parse_enum_def(&mut self, _generics: &Generics) -> PResult<'a, EnumDef> {
1541 let mut variants = Vec::new();
1542 while self.token != token::CloseDelim(token::Brace) {
1543 let variant_attrs = self.parse_outer_attributes()?;
1544 let vlo = self.token.span;
1547 let ident = self.parse_ident()?;
1549 let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
1550 // Parse a struct variant.
1551 let (fields, recovered) = self.parse_record_struct_body()?;
1552 VariantData::Struct(fields, recovered)
1553 } else if self.check(&token::OpenDelim(token::Paren)) {
1555 self.parse_tuple_struct_body()?,
1559 VariantData::Unit(DUMMY_NODE_ID)
1562 let disr_expr = if self.eat(&token::Eq) {
1565 value: self.parse_expr()?,
1571 let vr = ast::Variant {
1574 attrs: variant_attrs,
1577 span: vlo.to(self.prev_span),
1578 is_placeholder: false,
1582 if !self.eat(&token::Comma) {
1583 if self.token.is_ident() && !self.token.is_reserved_ident() {
1584 let sp = self.sess.source_map().next_point(self.prev_span);
1585 self.struct_span_err(sp, "missing comma")
1586 .span_suggestion_short(
1590 Applicability::MaybeIncorrect,
1598 self.expect(&token::CloseDelim(token::Brace))?;
1600 Ok(ast::EnumDef { variants })
1603 /// Parses `struct Foo { ... }`.
1604 fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
1605 let class_name = self.parse_ident()?;
1607 let mut generics = self.parse_generics()?;
1609 // There is a special case worth noting here, as reported in issue #17904.
1610 // If we are parsing a tuple struct it is the case that the where clause
1611 // should follow the field list. Like so:
1613 // struct Foo<T>(T) where T: Copy;
1615 // If we are parsing a normal record-style struct it is the case
1616 // that the where clause comes before the body, and after the generics.
1617 // So if we look ahead and see a brace or a where-clause we begin
1618 // parsing a record style struct.
1620 // Otherwise if we look ahead and see a paren we parse a tuple-style
1623 let vdata = if self.token.is_keyword(kw::Where) {
1624 generics.where_clause = self.parse_where_clause()?;
1625 if self.eat(&token::Semi) {
1626 // If we see a: `struct Foo<T> where T: Copy;` style decl.
1627 VariantData::Unit(DUMMY_NODE_ID)
1629 // If we see: `struct Foo<T> where T: Copy { ... }`
1630 let (fields, recovered) = self.parse_record_struct_body()?;
1631 VariantData::Struct(fields, recovered)
1633 // No `where` so: `struct Foo<T>;`
1634 } else if self.eat(&token::Semi) {
1635 VariantData::Unit(DUMMY_NODE_ID)
1636 // Record-style struct definition
1637 } else if self.token == token::OpenDelim(token::Brace) {
1638 let (fields, recovered) = self.parse_record_struct_body()?;
1639 VariantData::Struct(fields, recovered)
1640 // Tuple-style struct definition with optional where-clause.
1641 } else if self.token == token::OpenDelim(token::Paren) {
1642 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1643 generics.where_clause = self.parse_where_clause()?;
1644 self.expect(&token::Semi)?;
1647 let token_str = self.this_token_descr();
1648 let mut err = self.fatal(&format!(
1649 "expected `where`, `{{`, `(`, or `;` after struct name, found {}",
1652 err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name");
1656 Ok((class_name, ItemKind::Struct(vdata, generics), None))
1659 /// Parses `union Foo { ... }`.
1660 fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
1661 let class_name = self.parse_ident()?;
1663 let mut generics = self.parse_generics()?;
1665 let vdata = if self.token.is_keyword(kw::Where) {
1666 generics.where_clause = self.parse_where_clause()?;
1667 let (fields, recovered) = self.parse_record_struct_body()?;
1668 VariantData::Struct(fields, recovered)
1669 } else if self.token == token::OpenDelim(token::Brace) {
1670 let (fields, recovered) = self.parse_record_struct_body()?;
1671 VariantData::Struct(fields, recovered)
1673 let token_str = self.this_token_descr();
1674 let mut err = self.fatal(&format!(
1675 "expected `where` or `{{` after union name, found {}", token_str));
1676 err.span_label(self.token.span, "expected `where` or `{` after union name");
1680 Ok((class_name, ItemKind::Union(vdata, generics), None))
1683 pub(super) fn is_union_item(&self) -> bool {
1684 self.token.is_keyword(kw::Union) &&
1685 self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
1688 fn parse_record_struct_body(
1690 ) -> PResult<'a, (Vec<StructField>, /* recovered */ bool)> {
1691 let mut fields = Vec::new();
1692 let mut recovered = false;
1693 if self.eat(&token::OpenDelim(token::Brace)) {
1694 while self.token != token::CloseDelim(token::Brace) {
1695 let field = self.parse_struct_decl_field().map_err(|e| {
1696 self.recover_stmt();
1701 Ok(field) => fields.push(field),
1707 self.eat(&token::CloseDelim(token::Brace));
1709 let token_str = self.this_token_descr();
1710 let mut err = self.fatal(&format!(
1711 "expected `where`, or `{{` after struct name, found {}", token_str));
1712 err.span_label(self.token.span, "expected `where`, or `{` after struct name");
1716 Ok((fields, recovered))
1719 fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
1720 // This is the case where we find `struct Foo<T>(T) where T: Copy;`
1721 // Unit like structs are handled in parse_item_struct function
1722 self.parse_paren_comma_seq(|p| {
1723 let attrs = p.parse_outer_attributes()?;
1724 let lo = p.token.span;
1725 let vis = p.parse_visibility(true)?;
1726 let ty = p.parse_ty()?;
1728 span: lo.to(ty.span),
1734 is_placeholder: false,
1739 /// Parses an element of a struct declaration.
1740 fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
1741 let attrs = self.parse_outer_attributes()?;
1742 let lo = self.token.span;
1743 let vis = self.parse_visibility(false)?;
1744 self.parse_single_struct_field(lo, vis, attrs)
1747 /// Parses a structure field declaration.
1748 fn parse_single_struct_field(&mut self,
1751 attrs: Vec<Attribute> )
1752 -> PResult<'a, StructField> {
1753 let mut seen_comma: bool = false;
1754 let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
1755 if self.token == token::Comma {
1758 match self.token.kind {
1762 token::CloseDelim(token::Brace) => {}
1763 token::DocComment(_) => {
1764 let previous_span = self.prev_span;
1765 let mut err = self.span_fatal_err(self.token.span, Error::UselessDocComment);
1766 self.bump(); // consume the doc comment
1767 let comma_after_doc_seen = self.eat(&token::Comma);
1768 // `seen_comma` is always false, because we are inside doc block
1769 // condition is here to make code more readable
1770 if seen_comma == false && comma_after_doc_seen == true {
1773 if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) {
1776 if seen_comma == false {
1777 let sp = self.sess.source_map().next_point(previous_span);
1778 err.span_suggestion(
1780 "missing comma here",
1782 Applicability::MachineApplicable
1789 let sp = self.sess.source_map().next_point(self.prev_span);
1790 let mut err = self.struct_span_err(sp, &format!("expected `,`, or `}}`, found {}",
1791 self.this_token_descr()));
1792 if self.token.is_ident() {
1793 // This is likely another field; emit the diagnostic and keep going
1794 err.span_suggestion(
1796 "try adding a comma",
1798 Applicability::MachineApplicable,
1809 /// Parses a structure field.
1810 fn parse_name_and_ty(
1814 attrs: Vec<Attribute>
1815 ) -> PResult<'a, StructField> {
1816 let name = self.parse_ident()?;
1817 self.expect(&token::Colon)?;
1818 let ty = self.parse_ty()?;
1820 span: lo.to(self.prev_span),
1826 is_placeholder: false,
1830 pub(super) fn eat_macro_def(
1832 attrs: &[Attribute],
1835 ) -> PResult<'a, Option<P<Item>>> {
1836 let token_lo = self.token.span;
1837 let (ident, def) = if self.eat_keyword(kw::Macro) {
1838 let ident = self.parse_ident()?;
1839 let tokens = if self.check(&token::OpenDelim(token::Brace)) {
1840 match self.parse_token_tree() {
1841 TokenTree::Delimited(_, _, tts) => tts,
1842 _ => unreachable!(),
1844 } else if self.check(&token::OpenDelim(token::Paren)) {
1845 let args = self.parse_token_tree();
1846 let body = if self.check(&token::OpenDelim(token::Brace)) {
1847 self.parse_token_tree()
1852 TokenStream::new(vec![
1854 TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(),
1862 (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
1863 } else if self.check_keyword(sym::macro_rules) &&
1864 self.look_ahead(1, |t| *t == token::Not) &&
1865 self.look_ahead(2, |t| t.is_ident()) {
1866 let prev_span = self.prev_span;
1867 self.complain_if_pub_macro(&vis.node, prev_span);
1871 let ident = self.parse_ident()?;
1872 let (delim, tokens) = self.expect_delimited_token_tree()?;
1873 if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
1874 self.report_invalid_macro_expansion_item();
1877 (ident, ast::MacroDef { tokens, legacy: true })
1882 let span = lo.to(self.prev_span);
1883 Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
1886 fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
1888 VisibilityKind::Inherited => {}
1890 let mut err = if self.token.is_keyword(sym::macro_rules) {
1891 let mut err = self.diagnostic()
1892 .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
1893 err.span_suggestion(
1895 "try exporting the macro",
1896 "#[macro_export]".to_owned(),
1897 Applicability::MaybeIncorrect // speculative
1901 let mut err = self.diagnostic()
1902 .struct_span_err(sp, "can't qualify macro invocation with `pub`");
1903 err.help("try adjusting the macro to put `pub` inside the invocation");
1911 fn mk_item(&self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
1912 attrs: Vec<Attribute>) -> P<Item> {