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 = self.recover_first_param();
428 self.consume_block(token::Paren);
429 let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
430 self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
432 ("fn", kw_name, false)
433 } else if self.check(&token::OpenDelim(token::Brace)) {
435 ("fn", kw_name, false)
436 } else if self.check(&token::Colon) {
440 ("fn` or `struct", "function or struct", true)
443 let msg = format!("missing `{}` for {} definition", kw, kw_name);
444 let mut err = self.diagnostic().struct_span_err(sp, &msg);
446 self.consume_block(token::Brace);
447 let suggestion = format!("add `{}` here to parse `{}` as a public {}",
451 err.span_suggestion_short(
452 sp, &suggestion, format!(" {} ", kw), Applicability::MachineApplicable
455 if let Ok(snippet) = self.span_to_snippet(ident_sp) {
458 "if you meant to call a macro, try",
459 format!("{}!", snippet),
460 // this is the `ambiguous` conditional branch
461 Applicability::MaybeIncorrect
464 err.help("if you meant to call a macro, remove the `pub` \
465 and add a trailing `!` after the identifier");
469 } else if self.look_ahead(1, |t| *t == token::Lt) {
470 let ident = self.parse_ident().unwrap();
471 self.eat_to_tokens(&[&token::Gt]);
473 let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
474 ("fn", self.recover_first_param(), false)
475 } else if self.check(&token::OpenDelim(token::Brace)) {
476 ("struct", "struct", false)
478 ("fn` or `struct", "function or struct", true)
480 let msg = format!("missing `{}` for {} definition", kw, kw_name);
481 let mut err = self.diagnostic().struct_span_err(sp, &msg);
483 err.span_suggestion_short(
485 &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
487 Applicability::MachineApplicable,
493 self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
496 fn recover_first_param(&mut self) -> &'static str {
497 match self.parse_outer_attributes()
498 .and_then(|_| self.parse_self_param())
499 .map_err(|mut e| e.cancel())
501 Ok(Some(_)) => "method",
506 /// This is the fall-through for parsing items.
507 fn parse_macro_use_or_failure(
509 attrs: Vec<Attribute> ,
510 macros_allowed: bool,
511 attributes_allowed: bool,
513 visibility: Visibility
514 ) -> PResult<'a, Option<P<Item>>> {
515 if macros_allowed && self.token.is_path_start() &&
516 !(self.is_async_fn() && self.token.span.rust_2015()) {
517 // MACRO INVOCATION ITEM
519 let prev_span = self.prev_span;
520 self.complain_if_pub_macro(&visibility.node, prev_span);
522 let mac_lo = self.token.span;
525 let path = self.parse_path(PathStyle::Mod)?;
526 self.expect(&token::Not)?;
527 let (delim, tts) = self.expect_delimited_token_tree()?;
528 if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
529 self.report_invalid_macro_expansion_item();
532 let hi = self.prev_span;
538 prior_type_ascription: self.last_type_ascription,
541 self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs);
542 return Ok(Some(item));
545 // FAILURE TO PARSE ITEM
546 match visibility.node {
547 VisibilityKind::Inherited => {}
549 return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`"));
553 if !attributes_allowed && !attrs.is_empty() {
554 self.expected_item_err(&attrs)?;
559 /// Emits an expected-item-after-attributes error.
560 fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
561 let message = match attrs.last() {
562 Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
563 _ => "expected item after attributes",
566 let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
567 if attrs.last().unwrap().is_sugared_doc {
568 err.span_label(self.prev_span, "this doc comment doesn't document anything");
573 pub(super) fn is_async_fn(&self) -> bool {
574 self.token.is_keyword(kw::Async) &&
575 self.is_keyword_ahead(1, &[kw::Fn])
578 /// Parses a macro invocation inside a `trait`, `impl` or `extern` block.
579 fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
580 at_end: &mut bool) -> PResult<'a, Option<Mac>>
582 if self.token.is_path_start() &&
583 !(self.is_async_fn() && self.token.span.rust_2015()) {
584 let prev_span = self.prev_span;
585 let lo = self.token.span;
586 let path = self.parse_path(PathStyle::Mod)?;
588 if path.segments.len() == 1 {
589 if !self.eat(&token::Not) {
590 return Err(self.missing_assoc_item_kind_err(item_kind, prev_span));
593 self.expect(&token::Not)?;
596 if let Some(vis) = vis {
597 self.complain_if_pub_macro(&vis.node, prev_span);
602 // eat a matched-delimiter token tree:
603 let (delim, tts) = self.expect_delimited_token_tree()?;
604 if delim != MacDelimiter::Brace {
605 self.expect(&token::Semi)?;
612 span: lo.to(self.prev_span),
613 prior_type_ascription: self.last_type_ascription,
620 fn missing_assoc_item_kind_err(&self, item_type: &str, prev_span: Span)
621 -> DiagnosticBuilder<'a>
623 let expected_kinds = if item_type == "extern" {
624 "missing `fn`, `type`, or `static`"
626 "missing `fn`, `type`, or `const`"
629 // Given this code `path(`, it seems like this is not
630 // setting the visibility of a macro invocation, but rather
631 // a mistyped method declaration.
632 // Create a diagnostic pointing out that `fn` is missing.
634 // x | pub path(&self) {
635 // | ^ missing `fn`, `type`, or `const`
637 // ^^ `sp` below will point to this
638 let sp = prev_span.between(self.prev_span);
639 let mut err = self.diagnostic().struct_span_err(
641 &format!("{} for {}-item declaration",
642 expected_kinds, item_type));
643 err.span_label(sp, expected_kinds);
647 /// Parses an implementation item, `impl` keyword is already parsed.
649 /// impl<'a, T> TYPE { /* impl items */ }
650 /// impl<'a, T> TRAIT for TYPE { /* impl items */ }
651 /// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
653 /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
654 /// `impl` GENERICS `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}`
655 /// `impl` GENERICS `!`? TYPE (`where` PREDICATES)? `{` BODY `}`
656 fn parse_item_impl(&mut self, unsafety: Unsafety, defaultness: Defaultness)
657 -> PResult<'a, ItemInfo> {
658 // First, parse generic parameters if necessary.
659 let mut generics = if self.choose_generics_over_qpath() {
660 self.parse_generics()?
665 // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
666 let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
668 ast::ImplPolarity::Negative
670 ast::ImplPolarity::Positive
673 // Parse both types and traits as a type, then reinterpret if necessary.
674 let err_path = |span| ast::Path::from_ident(Ident::new(kw::Invalid, span));
675 let ty_first = if self.token.is_keyword(kw::For) &&
676 self.look_ahead(1, |t| t != &token::Lt) {
677 let span = self.prev_span.between(self.token.span);
678 self.struct_span_err(span, "missing trait in a trait impl").emit();
679 P(Ty { kind: TyKind::Path(None, err_path(span)), span, id: DUMMY_NODE_ID })
684 // If `for` is missing we try to recover.
685 let has_for = self.eat_keyword(kw::For);
686 let missing_for_span = self.prev_span.between(self.token.span);
688 let ty_second = if self.token == token::DotDot {
689 // We need to report this error after `cfg` expansion for compatibility reasons
690 self.bump(); // `..`, do not add it to expected tokens
691 Some(DummyResult::raw_ty(self.prev_span, true))
692 } else if has_for || self.token.can_begin_type() {
693 Some(self.parse_ty()?)
698 generics.where_clause = self.parse_where_clause()?;
700 let (impl_items, attrs) = self.parse_impl_body()?;
702 let item_kind = match ty_second {
704 // impl Trait for Type
706 self.struct_span_err(missing_for_span, "missing `for` in a trait impl")
707 .span_suggestion_short(
711 Applicability::MachineApplicable,
715 let ty_first = ty_first.into_inner();
716 let path = match ty_first.kind {
717 // This notably includes paths passed through `ty` macro fragments (#46438).
718 TyKind::Path(None, path) => path,
720 self.span_err(ty_first.span, "expected a trait, found type");
721 err_path(ty_first.span)
724 let trait_ref = TraitRef { path, ref_id: ty_first.id };
726 ItemKind::Impl(unsafety, polarity, defaultness,
727 generics, Some(trait_ref), ty_second, impl_items)
731 ItemKind::Impl(unsafety, polarity, defaultness,
732 generics, None, ty_first, impl_items)
736 Ok((Ident::invalid(), item_kind, Some(attrs)))
739 fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
740 self.expect(&token::OpenDelim(token::Brace))?;
741 let attrs = self.parse_inner_attributes()?;
743 let mut impl_items = Vec::new();
744 while !self.eat(&token::CloseDelim(token::Brace)) {
745 let mut at_end = false;
746 match self.parse_impl_item(&mut at_end) {
747 Ok(impl_item) => impl_items.push(impl_item),
751 self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
756 Ok((impl_items, attrs))
759 /// Parses an impl item.
760 pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
761 maybe_whole!(self, NtImplItem, |x| x);
762 let attrs = self.parse_outer_attributes()?;
763 let mut unclosed_delims = vec![];
764 let (mut item, tokens) = self.collect_tokens(|this| {
765 let item = this.parse_impl_item_(at_end, attrs);
766 unclosed_delims.append(&mut this.unclosed_delims);
769 self.unclosed_delims.append(&mut unclosed_delims);
771 // See `parse_item` for why this clause is here.
772 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
773 item.tokens = Some(tokens);
778 fn parse_impl_item_(&mut self,
780 mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> {
781 let lo = self.token.span;
782 let vis = self.parse_visibility(false)?;
783 let defaultness = self.parse_defaultness();
784 let (name, kind, generics) = if let Some(type_) = self.eat_type() {
785 let (name, alias, generics) = type_?;
786 let kind = match alias {
787 AliasKind::Weak(typ) => ast::ImplItemKind::TyAlias(typ),
788 AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
790 (name, kind, generics)
791 } else if self.is_const_item() {
792 // This parses the grammar:
793 // ImplItemConst = "const" Ident ":" Ty "=" Expr ";"
794 self.expect_keyword(kw::Const)?;
795 let name = self.parse_ident()?;
796 self.expect(&token::Colon)?;
797 let typ = self.parse_ty()?;
798 self.expect(&token::Eq)?;
799 let expr = self.parse_expr()?;
800 self.expect(&token::Semi)?;
801 (name, ast::ImplItemKind::Const(typ, expr), Generics::default())
803 let (name, inner_attrs, generics, kind) = self.parse_impl_method(&vis, at_end)?;
804 attrs.extend(inner_attrs);
805 (name, kind, generics)
810 span: lo.to(self.prev_span),
821 /// Parses defaultness (i.e., `default` or nothing).
822 fn parse_defaultness(&mut self) -> Defaultness {
823 // `pub` is included for better error messages
824 if self.check_keyword(kw::Default) &&
825 self.is_keyword_ahead(1, &[
836 self.bump(); // `default`
843 /// Returns `true` if we are looking at `const ID`
844 /// (returns `false` for things like `const fn`, etc.).
845 fn is_const_item(&self) -> bool {
846 self.token.is_keyword(kw::Const) &&
847 !self.is_keyword_ahead(1, &[kw::Fn, kw::Unsafe])
850 /// Parses a method or a macro invocation in a trait impl.
851 fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
852 -> PResult<'a, (Ident, Vec<Attribute>, Generics, ast::ImplItemKind)> {
853 // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
854 if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
856 Ok((Ident::invalid(), vec![], Generics::default(),
857 ast::ImplItemKind::Macro(mac)))
859 let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
860 let ident = self.parse_ident()?;
861 let mut generics = self.parse_generics()?;
862 let decl = self.parse_fn_decl_with_self(|_| true)?;
863 generics.where_clause = self.parse_where_clause()?;
865 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
866 let header = ast::FnHeader { abi, unsafety, constness, asyncness };
867 Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(
868 ast::MethodSig { header, decl },
874 /// Parses all the "front matter" for a `fn` declaration, up to
875 /// and including the `fn` keyword:
879 /// - `const unsafe fn`
882 fn parse_fn_front_matter(&mut self)
890 let is_const_fn = self.eat_keyword(kw::Const);
891 let const_span = self.prev_span;
892 let asyncness = self.parse_asyncness();
893 if let IsAsync::Async { .. } = asyncness {
894 self.ban_async_in_2015(self.prev_span);
896 let asyncness = respan(self.prev_span, asyncness);
897 let unsafety = self.parse_unsafety();
898 let (constness, unsafety, abi) = if is_const_fn {
899 (respan(const_span, Constness::Const), unsafety, Abi::Rust)
901 let abi = if self.eat_keyword(kw::Extern) {
902 self.parse_opt_abi()?.unwrap_or(Abi::C)
906 (respan(self.prev_span, Constness::NotConst), unsafety, abi)
908 if !self.eat_keyword(kw::Fn) {
909 // It is possible for `expect_one_of` to recover given the contents of
910 // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
912 if !self.expect_one_of(&[], &[])? { unreachable!() }
914 Ok((constness, unsafety, asyncness, abi))
917 /// Parses `trait Foo { ... }` or `trait Foo = Bar;`.
918 fn parse_item_trait(&mut self, is_auto: IsAuto, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
919 let ident = self.parse_ident()?;
920 let mut tps = self.parse_generics()?;
922 // Parse optional colon and supertrait bounds.
923 let bounds = if self.eat(&token::Colon) {
924 self.parse_generic_bounds(Some(self.prev_span))?
929 if self.eat(&token::Eq) {
930 // It's a trait alias.
931 let bounds = self.parse_generic_bounds(None)?;
932 tps.where_clause = self.parse_where_clause()?;
933 self.expect(&token::Semi)?;
934 if is_auto == IsAuto::Yes {
935 let msg = "trait aliases cannot be `auto`";
936 self.struct_span_err(self.prev_span, msg)
937 .span_label(self.prev_span, msg)
940 if unsafety != Unsafety::Normal {
941 let msg = "trait aliases cannot be `unsafe`";
942 self.struct_span_err(self.prev_span, msg)
943 .span_label(self.prev_span, msg)
946 Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
948 // It's a normal trait.
949 tps.where_clause = self.parse_where_clause()?;
950 self.expect(&token::OpenDelim(token::Brace))?;
951 let mut trait_items = vec![];
952 while !self.eat(&token::CloseDelim(token::Brace)) {
953 if let token::DocComment(_) = self.token.kind {
954 if self.look_ahead(1,
955 |tok| tok == &token::CloseDelim(token::Brace)) {
956 self.diagnostic().struct_span_err_with_code(
958 "found a documentation comment that doesn't document anything",
959 DiagnosticId::Error("E0584".into()),
962 "doc comments must come before what they document, maybe a \
963 comment was intended with `//`?",
970 let mut at_end = false;
971 match self.parse_trait_item(&mut at_end) {
972 Ok(item) => trait_items.push(item),
976 self.recover_stmt_(SemiColonMode::Break, BlockMode::Break);
981 Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None))
985 /// Parses the items in a trait declaration.
986 pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
987 maybe_whole!(self, NtTraitItem, |x| x);
988 let attrs = self.parse_outer_attributes()?;
989 let mut unclosed_delims = vec![];
990 let (mut item, tokens) = self.collect_tokens(|this| {
991 let item = this.parse_trait_item_(at_end, attrs);
992 unclosed_delims.append(&mut this.unclosed_delims);
995 self.unclosed_delims.append(&mut unclosed_delims);
996 // See `parse_item` for why this clause is here.
997 if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
998 item.tokens = Some(tokens);
1003 fn parse_trait_item_(&mut self,
1005 mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
1006 let lo = self.token.span;
1008 let (name, kind, generics) = if self.eat_keyword(kw::Type) {
1009 self.parse_trait_item_assoc_ty()?
1010 } else if self.is_const_item() {
1011 self.expect_keyword(kw::Const)?;
1012 let ident = self.parse_ident()?;
1013 self.expect(&token::Colon)?;
1014 let ty = self.parse_ty()?;
1015 let default = if self.eat(&token::Eq) {
1016 let expr = self.parse_expr()?;
1017 self.expect(&token::Semi)?;
1020 self.expect(&token::Semi)?;
1023 (ident, TraitItemKind::Const(ty, default), Generics::default())
1024 } else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
1025 // trait item macro.
1026 (Ident::invalid(), ast::TraitItemKind::Macro(mac), Generics::default())
1028 let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
1030 let ident = self.parse_ident()?;
1031 let mut generics = self.parse_generics()?;
1033 // This is somewhat dubious; We don't want to allow
1034 // argument names to be left off if there is a definition...
1036 // We don't allow argument names to be left off in edition 2018.
1037 let decl = self.parse_fn_decl_with_self(|t| t.span.rust_2018())?;
1038 generics.where_clause = self.parse_where_clause()?;
1040 let sig = ast::MethodSig {
1050 let body = match self.token.kind {
1054 debug!("parse_trait_methods(): parsing required method");
1057 token::OpenDelim(token::Brace) => {
1058 debug!("parse_trait_methods(): parsing provided method");
1060 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1061 attrs.extend(inner_attrs.iter().cloned());
1064 token::Interpolated(ref nt) => {
1066 token::NtBlock(..) => {
1068 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1069 attrs.extend(inner_attrs.iter().cloned());
1073 return self.expected_semi_or_open_brace();
1078 return self.expected_semi_or_open_brace();
1081 (ident, ast::TraitItemKind::Method(sig, body), generics)
1090 span: lo.to(self.prev_span),
1095 /// Parses the following grammar:
1097 /// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
1098 fn parse_trait_item_assoc_ty(&mut self)
1099 -> PResult<'a, (Ident, TraitItemKind, Generics)> {
1100 let ident = self.parse_ident()?;
1101 let mut generics = self.parse_generics()?;
1103 // Parse optional colon and param bounds.
1104 let bounds = if self.eat(&token::Colon) {
1105 self.parse_generic_bounds(None)?
1109 generics.where_clause = self.parse_where_clause()?;
1111 let default = if self.eat(&token::Eq) {
1112 Some(self.parse_ty()?)
1116 self.expect(&token::Semi)?;
1118 Ok((ident, TraitItemKind::Type(bounds, default), generics))
1121 /// Parses a `UseTree`.
1124 /// USE_TREE = [`::`] `*` |
1125 /// [`::`] `{` USE_TREE_LIST `}` |
1127 /// PATH `::` `{` USE_TREE_LIST `}` |
1128 /// PATH [`as` IDENT]
1130 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
1131 let lo = self.token.span;
1133 let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
1134 let kind = if self.check(&token::OpenDelim(token::Brace)) ||
1135 self.check(&token::BinOp(token::Star)) ||
1136 self.is_import_coupler() {
1137 // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
1138 let mod_sep_ctxt = self.token.span.ctxt();
1139 if self.eat(&token::ModSep) {
1140 prefix.segments.push(
1141 PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))
1145 if self.eat(&token::BinOp(token::Star)) {
1148 UseTreeKind::Nested(self.parse_use_tree_list()?)
1151 // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
1152 prefix = self.parse_path(PathStyle::Mod)?;
1154 if self.eat(&token::ModSep) {
1155 if self.eat(&token::BinOp(token::Star)) {
1158 UseTreeKind::Nested(self.parse_use_tree_list()?)
1161 UseTreeKind::Simple(self.parse_rename()?, DUMMY_NODE_ID, DUMMY_NODE_ID)
1165 Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) })
1168 /// Parses a `UseTreeKind::Nested(list)`.
1171 /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
1173 fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
1174 self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, DUMMY_NODE_ID)))
1178 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
1179 if self.eat_keyword(kw::As) {
1180 self.parse_ident_or_underscore().map(Some)
1186 fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
1187 match self.token.kind {
1188 token::Ident(name, false) if name == kw::Underscore => {
1189 let span = self.token.span;
1191 Ok(Ident::new(name, span))
1193 _ => self.parse_ident(),
1197 /// Parses `extern crate` links.
1202 /// extern crate foo;
1203 /// extern crate bar as foo;
1205 fn parse_item_extern_crate(
1208 visibility: Visibility,
1209 attrs: Vec<Attribute>
1210 ) -> PResult<'a, P<Item>> {
1211 // Accept `extern crate name-like-this` for better diagnostics
1212 let orig_name = self.parse_crate_name_with_dashes()?;
1213 let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
1214 (rename, Some(orig_name.name))
1218 self.expect(&token::Semi)?;
1220 let span = lo.to(self.prev_span);
1221 Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs))
1224 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
1225 let error_msg = "crate name using dashes are not valid in `extern crate` statements";
1226 let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
1228 let mut ident = if self.token.is_keyword(kw::SelfLower) {
1229 self.parse_path_segment_ident()
1233 let mut idents = vec![];
1234 let mut replacement = vec![];
1235 let mut fixed_crate_name = false;
1236 // Accept `extern crate name-like-this` for better diagnostics.
1237 let dash = token::BinOp(token::BinOpToken::Minus);
1238 if self.token == dash { // Do not include `-` as part of the expected tokens list.
1239 while self.eat(&dash) {
1240 fixed_crate_name = true;
1241 replacement.push((self.prev_span, "_".to_string()));
1242 idents.push(self.parse_ident()?);
1245 if fixed_crate_name {
1246 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
1247 let mut fixed_name = format!("{}", ident.name);
1248 for part in idents {
1249 fixed_name.push_str(&format!("_{}", part.name));
1251 ident = Ident::from_str_and_span(&fixed_name, fixed_name_sp);
1253 self.struct_span_err(fixed_name_sp, error_msg)
1254 .span_label(fixed_name_sp, "dash-separated idents are not valid")
1255 .multipart_suggestion(suggestion_msg, replacement, Applicability::MachineApplicable)
1261 /// Parses an item-position function declaration.
1265 asyncness: Spanned<IsAsync>,
1266 constness: Spanned<Constness>,
1268 ) -> PResult<'a, ItemInfo> {
1269 let (ident, mut generics) = self.parse_fn_header()?;
1270 let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe;
1271 let decl = self.parse_fn_decl(allow_c_variadic)?;
1272 generics.where_clause = self.parse_where_clause()?;
1273 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1274 let header = FnHeader { unsafety, asyncness, constness, abi };
1275 Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
1278 /// Parses the name and optional generic types of a function header.
1279 fn parse_fn_header(&mut self) -> PResult<'a, (Ident, Generics)> {
1280 let id = self.parse_ident()?;
1281 let generics = self.parse_generics()?;
1285 /// Parses the argument list and result type of a function declaration.
1286 fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P<FnDecl>> {
1287 let args = self.parse_fn_params(true, allow_c_variadic)?;
1288 let ret_ty = self.parse_ret_ty(true)?;
1296 /// Parses `extern` for foreign ABIs modules.
1298 /// `extern` is expected to have been
1299 /// consumed before calling this method.
1303 /// ```ignore (only-for-syntax-highlight)
1307 fn parse_item_foreign_mod(
1310 opt_abi: Option<Abi>,
1311 visibility: Visibility,
1312 mut attrs: Vec<Attribute>,
1314 ) -> PResult<'a, P<Item>> {
1315 self.expect(&token::OpenDelim(token::Brace))?;
1317 let abi = opt_abi.unwrap_or(Abi::C);
1319 attrs.extend(self.parse_inner_attributes()?);
1321 let mut foreign_items = vec![];
1322 while !self.eat(&token::CloseDelim(token::Brace)) {
1323 foreign_items.push(self.parse_foreign_item(extern_sp)?);
1326 let prev_span = self.prev_span;
1327 let m = ast::ForeignMod {
1329 items: foreign_items
1331 let invalid = Ident::invalid();
1332 Ok(self.mk_item(lo.to(prev_span), invalid, ItemKind::ForeignMod(m), visibility, attrs))
1335 /// Parses a foreign item.
1336 crate fn parse_foreign_item(&mut self, extern_sp: Span) -> PResult<'a, ForeignItem> {
1337 maybe_whole!(self, NtForeignItem, |ni| ni);
1339 let attrs = self.parse_outer_attributes()?;
1340 let lo = self.token.span;
1341 let visibility = self.parse_visibility(false)?;
1343 // FOREIGN STATIC ITEM
1344 // Treat `const` as `static` for error recovery, but don't add it to expected tokens.
1345 if self.check_keyword(kw::Static) || self.token.is_keyword(kw::Const) {
1346 if self.token.is_keyword(kw::Const) {
1348 .struct_span_err(self.token.span, "extern items cannot be `const`")
1351 "try using a static value",
1352 "static".to_owned(),
1353 Applicability::MachineApplicable
1356 self.bump(); // `static` or `const`
1357 return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?);
1359 // FOREIGN FUNCTION ITEM
1360 if self.check_keyword(kw::Fn) {
1361 return Ok(self.parse_item_foreign_fn(visibility, lo, attrs, extern_sp)?);
1363 // FOREIGN TYPE ITEM
1364 if self.check_keyword(kw::Type) {
1365 return Ok(self.parse_item_foreign_type(visibility, lo, attrs)?);
1368 match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? {
1372 ident: Ident::invalid(),
1373 span: lo.to(self.prev_span),
1377 kind: ForeignItemKind::Macro(mac),
1382 if !attrs.is_empty() {
1383 self.expected_item_err(&attrs)?;
1391 /// Parses a function declaration from a foreign module.
1392 fn parse_item_foreign_fn(
1394 vis: ast::Visibility,
1396 attrs: Vec<Attribute>,
1398 ) -> PResult<'a, ForeignItem> {
1399 self.expect_keyword(kw::Fn)?;
1401 let (ident, mut generics) = self.parse_fn_header()?;
1402 let decl = self.parse_fn_decl(true)?;
1403 generics.where_clause = self.parse_where_clause()?;
1404 let hi = self.token.span;
1405 self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
1406 Ok(ast::ForeignItem {
1409 kind: ForeignItemKind::Fn(decl, generics),
1416 /// Parses a static item from a foreign module.
1417 /// Assumes that the `static` keyword is already parsed.
1418 fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
1419 -> PResult<'a, ForeignItem> {
1420 let mutbl = self.parse_mutability();
1421 let ident = self.parse_ident()?;
1422 self.expect(&token::Colon)?;
1423 let ty = self.parse_ty()?;
1424 let hi = self.token.span;
1425 self.expect(&token::Semi)?;
1429 kind: ForeignItemKind::Static(ty, mutbl),
1436 /// Parses a type from a foreign module.
1437 fn parse_item_foreign_type(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
1438 -> PResult<'a, ForeignItem> {
1439 self.expect_keyword(kw::Type)?;
1441 let ident = self.parse_ident()?;
1442 let hi = self.token.span;
1443 self.expect(&token::Semi)?;
1444 Ok(ast::ForeignItem {
1447 kind: ForeignItemKind::Ty,
1454 fn is_static_global(&mut self) -> bool {
1455 if self.check_keyword(kw::Static) {
1456 // Check if this could be a closure.
1457 !self.look_ahead(1, |token| {
1458 if token.is_keyword(kw::Move) {
1462 token::BinOp(token::Or) | token::OrOr => true,
1471 /// Parse `["const" | ("static" "mut"?)] $ident ":" $ty = $expr` with
1472 /// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
1474 /// When `m` is `"const"`, `$ident` may also be `"_"`.
1475 fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
1476 let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
1478 // Parse the type of a `const` or `static mut?` item.
1479 // That is, the `":" $ty` fragment.
1480 let ty = if self.token == token::Eq {
1481 self.recover_missing_const_type(id, m)
1483 // Not `=` so expect `":"" $ty` as usual.
1484 self.expect(&token::Colon)?;
1488 self.expect(&token::Eq)?;
1489 let e = self.parse_expr()?;
1490 self.expect(&token::Semi)?;
1491 let item = match m {
1492 Some(m) => ItemKind::Static(ty, m, e),
1493 None => ItemKind::Const(ty, e),
1495 Ok((id, item, None))
1498 /// We were supposed to parse `:` but instead, we're already at `=`.
1499 /// This means that the type is missing.
1500 fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
1501 // Construct the error and stash it away with the hope
1502 // that typeck will later enrich the error with a type.
1503 let kind = match m {
1504 Some(Mutability::Mutable) => "static mut",
1505 Some(Mutability::Immutable) => "static",
1508 let mut err = self.struct_span_err(id.span, &format!("missing type for `{}` item", kind));
1509 err.span_suggestion(
1511 "provide a type for the item",
1512 format!("{}: <type>", id),
1513 Applicability::HasPlaceholders,
1515 err.stash(id.span, StashKey::ItemNoType);
1517 // The user intended that the type be inferred,
1518 // so treat this as if the user wrote e.g. `const A: _ = expr;`.
1520 kind: TyKind::Infer,
1522 id: ast::DUMMY_NODE_ID,
1526 /// Parses `type Foo = Bar;` or returns `None`
1527 /// without modifying the parser state.
1528 fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, Generics)>> {
1529 // This parses the grammar:
1530 // Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
1531 if self.eat_keyword(kw::Type) {
1532 Some(self.parse_type_alias())
1538 /// Parses a type alias or opaque type.
1539 fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, Generics)> {
1540 let ident = self.parse_ident()?;
1541 let mut tps = self.parse_generics()?;
1542 tps.where_clause = self.parse_where_clause()?;
1543 self.expect(&token::Eq)?;
1544 let alias = if self.check_keyword(kw::Impl) {
1546 let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
1547 AliasKind::OpaqueTy(bounds)
1549 let ty = self.parse_ty()?;
1552 self.expect(&token::Semi)?;
1553 Ok((ident, alias, tps))
1556 /// Parses an enum declaration.
1557 fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
1558 let id = self.parse_ident()?;
1559 let mut generics = self.parse_generics()?;
1560 generics.where_clause = self.parse_where_clause()?;
1561 self.expect(&token::OpenDelim(token::Brace))?;
1563 let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
1564 self.recover_stmt();
1565 self.eat(&token::CloseDelim(token::Brace));
1568 Ok((id, ItemKind::Enum(enum_definition, generics), None))
1571 /// Parses the part of an enum declaration following the `{`.
1572 fn parse_enum_def(&mut self, _generics: &Generics) -> PResult<'a, EnumDef> {
1573 let mut variants = Vec::new();
1574 while self.token != token::CloseDelim(token::Brace) {
1575 let variant_attrs = self.parse_outer_attributes()?;
1576 let vlo = self.token.span;
1579 let ident = self.parse_ident()?;
1581 let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
1582 // Parse a struct variant.
1583 let (fields, recovered) = self.parse_record_struct_body()?;
1584 VariantData::Struct(fields, recovered)
1585 } else if self.check(&token::OpenDelim(token::Paren)) {
1587 self.parse_tuple_struct_body()?,
1591 VariantData::Unit(DUMMY_NODE_ID)
1594 let disr_expr = if self.eat(&token::Eq) {
1597 value: self.parse_expr()?,
1603 let vr = ast::Variant {
1606 attrs: variant_attrs,
1609 span: vlo.to(self.prev_span),
1610 is_placeholder: false,
1614 if !self.eat(&token::Comma) {
1615 if self.token.is_ident() && !self.token.is_reserved_ident() {
1616 let sp = self.sess.source_map().next_point(self.prev_span);
1617 self.struct_span_err(sp, "missing comma")
1618 .span_suggestion_short(
1622 Applicability::MaybeIncorrect,
1630 self.expect(&token::CloseDelim(token::Brace))?;
1632 Ok(ast::EnumDef { variants })
1635 /// Parses `struct Foo { ... }`.
1636 fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
1637 let class_name = self.parse_ident()?;
1639 let mut generics = self.parse_generics()?;
1641 // There is a special case worth noting here, as reported in issue #17904.
1642 // If we are parsing a tuple struct it is the case that the where clause
1643 // should follow the field list. Like so:
1645 // struct Foo<T>(T) where T: Copy;
1647 // If we are parsing a normal record-style struct it is the case
1648 // that the where clause comes before the body, and after the generics.
1649 // So if we look ahead and see a brace or a where-clause we begin
1650 // parsing a record style struct.
1652 // Otherwise if we look ahead and see a paren we parse a tuple-style
1655 let vdata = if self.token.is_keyword(kw::Where) {
1656 generics.where_clause = self.parse_where_clause()?;
1657 if self.eat(&token::Semi) {
1658 // If we see a: `struct Foo<T> where T: Copy;` style decl.
1659 VariantData::Unit(DUMMY_NODE_ID)
1661 // If we see: `struct Foo<T> where T: Copy { ... }`
1662 let (fields, recovered) = self.parse_record_struct_body()?;
1663 VariantData::Struct(fields, recovered)
1665 // No `where` so: `struct Foo<T>;`
1666 } else if self.eat(&token::Semi) {
1667 VariantData::Unit(DUMMY_NODE_ID)
1668 // Record-style struct definition
1669 } else if self.token == token::OpenDelim(token::Brace) {
1670 let (fields, recovered) = self.parse_record_struct_body()?;
1671 VariantData::Struct(fields, recovered)
1672 // Tuple-style struct definition with optional where-clause.
1673 } else if self.token == token::OpenDelim(token::Paren) {
1674 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
1675 generics.where_clause = self.parse_where_clause()?;
1676 self.expect(&token::Semi)?;
1679 let token_str = self.this_token_descr();
1680 let mut err = self.fatal(&format!(
1681 "expected `where`, `{{`, `(`, or `;` after struct name, found {}",
1684 err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name");
1688 Ok((class_name, ItemKind::Struct(vdata, generics), None))
1691 /// Parses `union Foo { ... }`.
1692 fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
1693 let class_name = self.parse_ident()?;
1695 let mut generics = self.parse_generics()?;
1697 let vdata = if self.token.is_keyword(kw::Where) {
1698 generics.where_clause = self.parse_where_clause()?;
1699 let (fields, recovered) = self.parse_record_struct_body()?;
1700 VariantData::Struct(fields, recovered)
1701 } else if self.token == token::OpenDelim(token::Brace) {
1702 let (fields, recovered) = self.parse_record_struct_body()?;
1703 VariantData::Struct(fields, recovered)
1705 let token_str = self.this_token_descr();
1706 let mut err = self.fatal(&format!(
1707 "expected `where` or `{{` after union name, found {}", token_str));
1708 err.span_label(self.token.span, "expected `where` or `{` after union name");
1712 Ok((class_name, ItemKind::Union(vdata, generics), None))
1715 pub(super) fn is_union_item(&self) -> bool {
1716 self.token.is_keyword(kw::Union) &&
1717 self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
1720 fn parse_record_struct_body(
1722 ) -> PResult<'a, (Vec<StructField>, /* recovered */ bool)> {
1723 let mut fields = Vec::new();
1724 let mut recovered = false;
1725 if self.eat(&token::OpenDelim(token::Brace)) {
1726 while self.token != token::CloseDelim(token::Brace) {
1727 let field = self.parse_struct_decl_field().map_err(|e| {
1728 self.recover_stmt();
1733 Ok(field) => fields.push(field),
1739 self.eat(&token::CloseDelim(token::Brace));
1741 let token_str = self.this_token_descr();
1742 let mut err = self.fatal(&format!(
1743 "expected `where`, or `{{` after struct name, found {}", token_str));
1744 err.span_label(self.token.span, "expected `where`, or `{` after struct name");
1748 Ok((fields, recovered))
1751 fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
1752 // This is the case where we find `struct Foo<T>(T) where T: Copy;`
1753 // Unit like structs are handled in parse_item_struct function
1754 self.parse_paren_comma_seq(|p| {
1755 let attrs = p.parse_outer_attributes()?;
1756 let lo = p.token.span;
1757 let vis = p.parse_visibility(true)?;
1758 let ty = p.parse_ty()?;
1760 span: lo.to(ty.span),
1766 is_placeholder: false,
1771 /// Parses an element of a struct declaration.
1772 fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
1773 let attrs = self.parse_outer_attributes()?;
1774 let lo = self.token.span;
1775 let vis = self.parse_visibility(false)?;
1776 self.parse_single_struct_field(lo, vis, attrs)
1779 /// Parses a structure field declaration.
1780 fn parse_single_struct_field(&mut self,
1783 attrs: Vec<Attribute> )
1784 -> PResult<'a, StructField> {
1785 let mut seen_comma: bool = false;
1786 let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
1787 if self.token == token::Comma {
1790 match self.token.kind {
1794 token::CloseDelim(token::Brace) => {}
1795 token::DocComment(_) => {
1796 let previous_span = self.prev_span;
1797 let mut err = self.span_fatal_err(self.token.span, Error::UselessDocComment);
1798 self.bump(); // consume the doc comment
1799 let comma_after_doc_seen = self.eat(&token::Comma);
1800 // `seen_comma` is always false, because we are inside doc block
1801 // condition is here to make code more readable
1802 if seen_comma == false && comma_after_doc_seen == true {
1805 if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) {
1808 if seen_comma == false {
1809 let sp = self.sess.source_map().next_point(previous_span);
1810 err.span_suggestion(
1812 "missing comma here",
1814 Applicability::MachineApplicable
1821 let sp = self.sess.source_map().next_point(self.prev_span);
1822 let mut err = self.struct_span_err(sp, &format!("expected `,`, or `}}`, found {}",
1823 self.this_token_descr()));
1824 if self.token.is_ident() {
1825 // This is likely another field; emit the diagnostic and keep going
1826 err.span_suggestion(
1828 "try adding a comma",
1830 Applicability::MachineApplicable,
1841 /// Parses a structure field.
1842 fn parse_name_and_ty(
1846 attrs: Vec<Attribute>
1847 ) -> PResult<'a, StructField> {
1848 let name = self.parse_ident()?;
1849 self.expect(&token::Colon)?;
1850 let ty = self.parse_ty()?;
1852 span: lo.to(self.prev_span),
1858 is_placeholder: false,
1862 pub(super) fn eat_macro_def(
1864 attrs: &[Attribute],
1867 ) -> PResult<'a, Option<P<Item>>> {
1868 let token_lo = self.token.span;
1869 let (ident, def) = if self.eat_keyword(kw::Macro) {
1870 let ident = self.parse_ident()?;
1871 let tokens = if self.check(&token::OpenDelim(token::Brace)) {
1872 match self.parse_token_tree() {
1873 TokenTree::Delimited(_, _, tts) => tts,
1874 _ => unreachable!(),
1876 } else if self.check(&token::OpenDelim(token::Paren)) {
1877 let args = self.parse_token_tree();
1878 let body = if self.check(&token::OpenDelim(token::Brace)) {
1879 self.parse_token_tree()
1884 TokenStream::new(vec![
1886 TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(),
1894 (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
1895 } else if self.check_keyword(sym::macro_rules) &&
1896 self.look_ahead(1, |t| *t == token::Not) &&
1897 self.look_ahead(2, |t| t.is_ident()) {
1898 let prev_span = self.prev_span;
1899 self.complain_if_pub_macro(&vis.node, prev_span);
1903 let ident = self.parse_ident()?;
1904 let (delim, tokens) = self.expect_delimited_token_tree()?;
1905 if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
1906 self.report_invalid_macro_expansion_item();
1909 (ident, ast::MacroDef { tokens, legacy: true })
1914 let span = lo.to(self.prev_span);
1915 Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
1918 fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
1920 VisibilityKind::Inherited => {}
1922 let mut err = if self.token.is_keyword(sym::macro_rules) {
1923 let mut err = self.diagnostic()
1924 .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
1925 err.span_suggestion(
1927 "try exporting the macro",
1928 "#[macro_export]".to_owned(),
1929 Applicability::MaybeIncorrect // speculative
1933 let mut err = self.diagnostic()
1934 .struct_span_err(sp, "can't qualify macro invocation with `pub`");
1935 err.help("try adjusting the macro to put `pub` inside the invocation");
1943 fn mk_item(&self, span: Span, ident: Ident, kind: ItemKind, vis: Visibility,
1944 attrs: Vec<Attribute>) -> P<Item> {