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, StashKey};
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 /// Parse `["const" | ("static" "mut"?)] $ident ":" $ty = $expr` with
1481 /// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
1483 /// When `m` is `"const"`, `$ident` may also be `"_"`.
1484 fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
1485 let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
1487 // Parse the type of a `const` or `static mut?` item.
1488 // That is, the `":" $ty` fragment.
1489 let ty = if self.token == token::Eq {
1490 self.recover_missing_const_type(id, m)
1492 // Not `=` so expect `":"" $ty` as usual.
1493 self.expect(&token::Colon)?;
1497 self.expect(&token::Eq)?;
1498 let e = self.parse_expr()?;
1499 self.expect(&token::Semi)?;
1500 let item = match m {
1501 Some(m) => ItemKind::Static(ty, m, e),
1502 None => ItemKind::Const(ty, e),
1504 Ok((id, item, None))
1507 /// We were supposed to parse `:` but instead, we're already at `=`.
1508 /// This means that the type is missing.
1509 fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
1510 // Construct the error and stash it away with the hope
1511 // that typeck will later enrich the error with a type.
1512 let kind = match m {
1513 Some(Mutability::Mutable) => "static mut",
1514 Some(Mutability::Immutable) => "static",
1517 let mut err = self.struct_span_err(id.span, &format!("missing type for `{}` item", kind));
1518 err.span_suggestion(
1520 "provide a type for the item",
1521 format!("{}: <type>", id),
1522 Applicability::HasPlaceholders,
1524 err.stash(id.span, StashKey::ItemNoType);
1526 // The user intended that the type be inferred,
1527 // so treat this as if the user wrote e.g. `const A: _ = expr;`.
1529 node: TyKind::Infer,
1531 id: ast::DUMMY_NODE_ID,
1535 /// Parses `type Foo = Bar;` or returns `None`
1536 /// without modifying the parser state.
1537 fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, Generics)>> {
1538 // This parses the grammar:
1539 // Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
1540 if self.eat_keyword(kw::Type) {
1541 Some(self.parse_type_alias())
1547 /// Parses a type alias or opaque type.
1548 fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, Generics)> {
1549 let ident = self.parse_ident()?;
1550 let mut tps = self.parse_generics()?;
1551 tps.where_clause = self.parse_where_clause()?;
1552 self.expect(&token::Eq)?;
1553 let alias = if self.check_keyword(kw::Impl) {
1555 let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
1556 AliasKind::OpaqueTy(bounds)
1558 let ty = self.parse_ty()?;
1561 self.expect(&token::Semi)?;
1562 Ok((ident, alias, tps))
1565 /// Parses an enum declaration.
1566 fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
1567 let id = self.parse_ident()?;
1568 let mut generics = self.parse_generics()?;
1569 generics.where_clause = self.parse_where_clause()?;
1570 self.expect(&token::OpenDelim(token::Brace))?;
1572 let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
1573 self.recover_stmt();
1574 self.eat(&token::CloseDelim(token::Brace));
1577 Ok((id, ItemKind::Enum(enum_definition, generics), None))
1580 /// Parses the part of an enum declaration following the `{`.
1581 fn parse_enum_def(&mut self, _generics: &Generics) -> PResult<'a, EnumDef> {
1582 let mut variants = Vec::new();
1583 while self.token != token::CloseDelim(token::Brace) {
1584 let variant_attrs = self.parse_outer_attributes()?;
1585 let vlo = self.token.span;
1588 let ident = self.parse_ident()?;
1590 let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
1591 // Parse a struct variant.
1592 let (fields, recovered) = self.parse_record_struct_body()?;
1593 VariantData::Struct(fields, recovered)
1594 } else if self.check(&token::OpenDelim(token::Paren)) {
1596 self.parse_tuple_struct_body()?,
1600 VariantData::Unit(DUMMY_NODE_ID)
1603 let disr_expr = if self.eat(&token::Eq) {
1606 value: self.parse_expr()?,
1612 let vr = ast::Variant {
1615 attrs: variant_attrs,
1618 span: vlo.to(self.prev_span),
1619 is_placeholder: false,
1623 if !self.eat(&token::Comma) {
1624 if self.token.is_ident() && !self.token.is_reserved_ident() {
1625 let sp = self.sess.source_map().next_point(self.prev_span);
1626 self.struct_span_err(sp, "missing comma")
1627 .span_suggestion_short(
1631 Applicability::MaybeIncorrect,
1639 self.expect(&token::CloseDelim(token::Brace))?;
1641 Ok(ast::EnumDef { variants })
1644 /// Parses `struct Foo { ... }`.
1645 fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
1646 let class_name = self.parse_ident()?;
1648 let mut generics = self.parse_generics()?;
1650 // There is a special case worth noting here, as reported in issue #17904.
1651 // If we are parsing a tuple struct it is the case that the where clause
1652 // should follow the field list. Like so:
1654 // struct Foo<T>(T) where T: Copy;
1656 // If we are parsing a normal record-style struct it is the case
1657 // that the where clause comes before the body, and after the generics.
1658 // So if we look ahead and see a brace or a where-clause we begin
1659 // parsing a record style struct.
1661 // Otherwise if we look ahead and see a paren we parse a tuple-style
1664 let vdata = if self.token.is_keyword(kw::Where) {
1665 generics.where_clause = self.parse_where_clause()?;
1666 if self.eat(&token::Semi) {
1667 // If we see a: `struct Foo<T> where T: Copy;` style decl.
1668 VariantData::Unit(DUMMY_NODE_ID)
1670 // If we see: `struct Foo<T> where T: Copy { ... }`
1671 let (fields, recovered) = self.parse_record_struct_body()?;
1672 VariantData::Struct(fields, recovered)
1674 // No `where` so: `struct Foo<T>;`
1675 } else if self.eat(&token::Semi) {
1676 VariantData::Unit(DUMMY_NODE_ID)
1677 // Record-style struct definition
1678 } else if self.token == token::OpenDelim(token::Brace) {
1679 let (fields, recovered) = self.parse_record_struct_body()?;
1680 VariantData::Struct(fields, recovered)
1681 // Tuple-style struct definition with optional where-clause.
1682 } else if self.token == token::OpenDelim(token::Paren) {
1683 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1684 generics.where_clause = self.parse_where_clause()?;
1685 self.expect(&token::Semi)?;
1688 let token_str = self.this_token_descr();
1689 let mut err = self.fatal(&format!(
1690 "expected `where`, `{{`, `(`, or `;` after struct name, found {}",
1693 err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name");
1697 Ok((class_name, ItemKind::Struct(vdata, generics), None))
1700 /// Parses `union Foo { ... }`.
1701 fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
1702 let class_name = self.parse_ident()?;
1704 let mut generics = self.parse_generics()?;
1706 let vdata = if self.token.is_keyword(kw::Where) {
1707 generics.where_clause = self.parse_where_clause()?;
1708 let (fields, recovered) = self.parse_record_struct_body()?;
1709 VariantData::Struct(fields, recovered)
1710 } else if self.token == token::OpenDelim(token::Brace) {
1711 let (fields, recovered) = self.parse_record_struct_body()?;
1712 VariantData::Struct(fields, recovered)
1714 let token_str = self.this_token_descr();
1715 let mut err = self.fatal(&format!(
1716 "expected `where` or `{{` after union name, found {}", token_str));
1717 err.span_label(self.token.span, "expected `where` or `{` after union name");
1721 Ok((class_name, ItemKind::Union(vdata, generics), None))
1724 pub(super) fn is_union_item(&self) -> bool {
1725 self.token.is_keyword(kw::Union) &&
1726 self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
1729 fn parse_record_struct_body(
1731 ) -> PResult<'a, (Vec<StructField>, /* recovered */ bool)> {
1732 let mut fields = Vec::new();
1733 let mut recovered = false;
1734 if self.eat(&token::OpenDelim(token::Brace)) {
1735 while self.token != token::CloseDelim(token::Brace) {
1736 let field = self.parse_struct_decl_field().map_err(|e| {
1737 self.recover_stmt();
1742 Ok(field) => fields.push(field),
1748 self.eat(&token::CloseDelim(token::Brace));
1750 let token_str = self.this_token_descr();
1751 let mut err = self.fatal(&format!(
1752 "expected `where`, or `{{` after struct name, found {}", token_str));
1753 err.span_label(self.token.span, "expected `where`, or `{` after struct name");
1757 Ok((fields, recovered))
1760 fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
1761 // This is the case where we find `struct Foo<T>(T) where T: Copy;`
1762 // Unit like structs are handled in parse_item_struct function
1763 self.parse_paren_comma_seq(|p| {
1764 let attrs = p.parse_outer_attributes()?;
1765 let lo = p.token.span;
1766 let vis = p.parse_visibility(true)?;
1767 let ty = p.parse_ty()?;
1769 span: lo.to(ty.span),
1775 is_placeholder: false,
1780 /// Parses an element of a struct declaration.
1781 fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
1782 let attrs = self.parse_outer_attributes()?;
1783 let lo = self.token.span;
1784 let vis = self.parse_visibility(false)?;
1785 self.parse_single_struct_field(lo, vis, attrs)
1788 /// Parses a structure field declaration.
1789 fn parse_single_struct_field(&mut self,
1792 attrs: Vec<Attribute> )
1793 -> PResult<'a, StructField> {
1794 let mut seen_comma: bool = false;
1795 let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
1796 if self.token == token::Comma {
1799 match self.token.kind {
1803 token::CloseDelim(token::Brace) => {}
1804 token::DocComment(_) => {
1805 let previous_span = self.prev_span;
1806 let mut err = self.span_fatal_err(self.token.span, Error::UselessDocComment);
1807 self.bump(); // consume the doc comment
1808 let comma_after_doc_seen = self.eat(&token::Comma);
1809 // `seen_comma` is always false, because we are inside doc block
1810 // condition is here to make code more readable
1811 if seen_comma == false && comma_after_doc_seen == true {
1814 if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) {
1817 if seen_comma == false {
1818 let sp = self.sess.source_map().next_point(previous_span);
1819 err.span_suggestion(
1821 "missing comma here",
1823 Applicability::MachineApplicable
1830 let sp = self.sess.source_map().next_point(self.prev_span);
1831 let mut err = self.struct_span_err(sp, &format!("expected `,`, or `}}`, found {}",
1832 self.this_token_descr()));
1833 if self.token.is_ident() {
1834 // This is likely another field; emit the diagnostic and keep going
1835 err.span_suggestion(
1837 "try adding a comma",
1839 Applicability::MachineApplicable,
1850 /// Parses a structure field.
1851 fn parse_name_and_ty(
1855 attrs: Vec<Attribute>
1856 ) -> PResult<'a, StructField> {
1857 let name = self.parse_ident()?;
1858 self.expect(&token::Colon)?;
1859 let ty = self.parse_ty()?;
1861 span: lo.to(self.prev_span),
1867 is_placeholder: false,
1871 pub(super) fn eat_macro_def(
1873 attrs: &[Attribute],
1876 ) -> PResult<'a, Option<P<Item>>> {
1877 let token_lo = self.token.span;
1878 let (ident, def) = if self.eat_keyword(kw::Macro) {
1879 let ident = self.parse_ident()?;
1880 let tokens = if self.check(&token::OpenDelim(token::Brace)) {
1881 match self.parse_token_tree() {
1882 TokenTree::Delimited(_, _, tts) => tts,
1883 _ => unreachable!(),
1885 } else if self.check(&token::OpenDelim(token::Paren)) {
1886 let args = self.parse_token_tree();
1887 let body = if self.check(&token::OpenDelim(token::Brace)) {
1888 self.parse_token_tree()
1893 TokenStream::new(vec![
1895 TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(),
1903 (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
1904 } else if self.check_keyword(sym::macro_rules) &&
1905 self.look_ahead(1, |t| *t == token::Not) &&
1906 self.look_ahead(2, |t| t.is_ident()) {
1907 let prev_span = self.prev_span;
1908 self.complain_if_pub_macro(&vis.node, prev_span);
1912 let ident = self.parse_ident()?;
1913 let (delim, tokens) = self.expect_delimited_token_tree()?;
1914 if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
1915 self.report_invalid_macro_expansion_item();
1918 (ident, ast::MacroDef { tokens, legacy: true })
1923 let span = lo.to(self.prev_span);
1924 Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
1927 fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
1929 VisibilityKind::Inherited => {}
1931 let mut err = if self.token.is_keyword(sym::macro_rules) {
1932 let mut err = self.diagnostic()
1933 .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
1934 err.span_suggestion(
1936 "try exporting the macro",
1937 "#[macro_export]".to_owned(),
1938 Applicability::MaybeIncorrect // speculative
1942 let mut err = self.diagnostic()
1943 .struct_span_err(sp, "can't qualify macro invocation with `pub`");
1944 err.help("try adjusting the macro to put `pub` inside the invocation");
1952 fn mk_item(&self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
1953 attrs: Vec<Attribute>) -> P<Item> {