]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_parse/src/parser/item.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / compiler / rustc_parse / src / parser / item.rs
CommitLineData
dfeec247 1use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
fc512014 2use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
6a06907d 3use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
416331ca 4
5869c6ff 5use rustc_ast::ast::*;
74b04a01 6use rustc_ast::ptr::P;
ba9703b0 7use rustc_ast::token::{self, TokenKind};
74b04a01 8use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
29967ef6 9use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID};
3dfed10e
XL
10use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
11use rustc_ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind};
6a06907d 12use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData};
3dfed10e
XL
13use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
14use rustc_ast::{MacArgs, MacCall, MacDelimiter};
74b04a01
XL
15use rustc_ast_pretty::pprust;
16use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
5869c6ff 17use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
74b04a01 18use rustc_span::source_map::{self, Span};
f9f354fc 19use rustc_span::symbol::{kw, sym, Ident, Symbol};
416331ca 20
74b04a01 21use std::convert::TryFrom;
60c5eb7d 22use std::mem;
3dfed10e 23use tracing::debug;
416331ca 24
ba9703b0
XL
25impl<'a> Parser<'a> {
26 /// Parses a source module as a crate. This is the main entry point for the parser.
27 pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> {
6a06907d 28 let (attrs, items, span) = self.parse_mod(&token::Eof)?;
ba9703b0 29 let proc_macros = Vec::new(); // Filled in by `proc_macro_harness::inject()`.
6a06907d 30 Ok(ast::Crate { attrs, items, span, proc_macros })
ba9703b0
XL
31 }
32
33 /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
34 fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
1b1a35ee
XL
35 let unsafety = self.parse_unsafety();
36 self.expect_keyword(kw::Mod)?;
ba9703b0 37 let id = self.parse_ident()?;
6a06907d
XL
38 let mod_kind = if self.eat(&token::Semi) {
39 ModKind::Unloaded
ba9703b0
XL
40 } else {
41 self.expect(&token::OpenDelim(token::Brace))?;
6a06907d
XL
42 let (mut inner_attrs, items, inner_span) =
43 self.parse_mod(&token::CloseDelim(token::Brace))?;
44 attrs.append(&mut inner_attrs);
45 ModKind::Loaded(items, Inline::Yes, inner_span)
ba9703b0 46 };
6a06907d 47 Ok((id, ItemKind::Mod(unsafety, mod_kind)))
ba9703b0
XL
48 }
49
50 /// Parses the contents of a module (inner attributes followed by module items).
1b1a35ee
XL
51 pub fn parse_mod(
52 &mut self,
53 term: &TokenKind,
6a06907d 54 ) -> PResult<'a, (Vec<Attribute>, Vec<P<Item>>, Span)> {
ba9703b0
XL
55 let lo = self.token.span;
56 let attrs = self.parse_inner_attributes()?;
ba9703b0 57
ba9703b0 58 let mut items = vec![];
5869c6ff 59 while let Some(item) = self.parse_item(ForceCollect::No)? {
ba9703b0
XL
60 items.push(item);
61 self.maybe_consume_incorrect_semicolon(&items);
62 }
63
64 if !self.eat(term) {
65 let token_str = super::token_descr(&self.token);
66 if !self.maybe_consume_incorrect_semicolon(&items) {
67 let msg = &format!("expected item, found {}", token_str);
68 let mut err = self.struct_span_err(self.token.span, msg);
69 err.span_label(self.token.span, "expected item");
70 return Err(err);
71 }
72 }
73
6a06907d 74 Ok((attrs, items, lo.to(self.prev_token.span)))
ba9703b0
XL
75 }
76}
77
74b04a01 78pub(super) type ItemInfo = (Ident, ItemKind);
416331ca
XL
79
80impl<'a> Parser<'a> {
5869c6ff
XL
81 pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<P<Item>>> {
82 self.parse_item_(|_| true, force_collect).map(|i| i.map(P))
74b04a01
XL
83 }
84
5869c6ff
XL
85 fn parse_item_(
86 &mut self,
87 req_name: ReqName,
88 force_collect: ForceCollect,
89 ) -> PResult<'a, Option<Item>> {
416331ca 90 let attrs = self.parse_outer_attributes()?;
5869c6ff 91 self.parse_item_common(attrs, true, false, req_name, force_collect)
416331ca
XL
92 }
93
74b04a01 94 pub(super) fn parse_item_common(
416331ca 95 &mut self,
6a06907d 96 attrs: AttrWrapper,
74b04a01
XL
97 mac_allowed: bool,
98 attrs_allowed: bool,
99 req_name: ReqName,
5869c6ff 100 force_collect: ForceCollect,
74b04a01 101 ) -> PResult<'a, Option<Item>> {
6a06907d
XL
102 // Don't use `maybe_whole` so that we have precise control
103 // over when we bump the parser
104 if let token::Interpolated(nt) = &self.token.kind {
105 if let token::NtItem(item) = &**nt {
106 let item = item.clone();
107
108 return self.collect_tokens_trailing_token(
109 attrs,
110 force_collect,
111 |this, mut attrs| {
112 let mut item = item;
113 mem::swap(&mut item.attrs, &mut attrs);
114 item.attrs.extend(attrs);
115 // Bump the parser so the we capture the token::Interpolated
116 this.bump();
117 Ok((Some(item.into_inner()), TrailingToken::None))
118 },
119 );
120 }
121 };
74b04a01 122
416331ca 123 let mut unclosed_delims = vec![];
6a06907d
XL
124 let item =
125 self.collect_tokens_trailing_token(attrs, force_collect, |this: &mut Self, attrs| {
126 let item = this.parse_item_common_(attrs, mac_allowed, attrs_allowed, req_name);
127 unclosed_delims.append(&mut this.unclosed_delims);
128 Ok((item?, TrailingToken::None))
129 })?;
29967ef6
XL
130
131 self.unclosed_delims.append(&mut unclosed_delims);
74b04a01 132 Ok(item)
416331ca
XL
133 }
134
74b04a01 135 fn parse_item_common_(
416331ca 136 &mut self,
74b04a01
XL
137 mut attrs: Vec<Attribute>,
138 mac_allowed: bool,
139 attrs_allowed: bool,
140 req_name: ReqName,
141 ) -> PResult<'a, Option<Item>> {
416331ca 142 let lo = self.token.span;
60c5eb7d 143 let vis = self.parse_visibility(FollowedByType::No)?;
74b04a01
XL
144 let mut def = self.parse_defaultness();
145 let kind = self.parse_item_kind(&mut attrs, mac_allowed, lo, &vis, &mut def, req_name)?;
146 if let Some((ident, kind)) = kind {
147 self.error_on_unconsumed_default(def, &kind);
148 let span = lo.to(self.prev_token.span);
149 let id = DUMMY_NODE_ID;
150 let item = Item { ident, attrs, id, kind, vis, span, tokens: None };
416331ca
XL
151 return Ok(Some(item));
152 }
153
74b04a01
XL
154 // At this point, we have failed to parse an item.
155 self.error_on_unmatched_vis(&vis);
156 self.error_on_unmatched_defaultness(def);
157 if !attrs_allowed {
158 self.recover_attrs_no_item(&attrs)?;
416331ca 159 }
74b04a01
XL
160 Ok(None)
161 }
416331ca 162
74b04a01
XL
163 /// Error in-case a non-inherited visibility was parsed but no item followed.
164 fn error_on_unmatched_vis(&self, vis: &Visibility) {
1b1a35ee 165 if let VisibilityKind::Inherited = vis.kind {
74b04a01 166 return;
416331ca 167 }
74b04a01
XL
168 let vs = pprust::vis_to_string(&vis);
169 let vs = vs.trim_end();
170 self.struct_span_err(vis.span, &format!("visibility `{}` is not followed by an item", vs))
171 .span_label(vis.span, "the visibility")
172 .help(&format!("you likely meant to define an item, e.g., `{} fn foo() {{}}`", vs))
173 .emit();
174 }
e74abb32 175
74b04a01
XL
176 /// Error in-case a `default` was parsed but no item followed.
177 fn error_on_unmatched_defaultness(&self, def: Defaultness) {
178 if let Defaultness::Default(sp) = def {
179 self.struct_span_err(sp, "`default` is not followed by an item")
180 .span_label(sp, "the `default` qualifier")
181 .note("only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`")
182 .emit();
416331ca 183 }
74b04a01 184 }
416331ca 185
74b04a01
XL
186 /// Error in-case `default` was parsed in an in-appropriate context.
187 fn error_on_unconsumed_default(&self, def: Defaultness, kind: &ItemKind) {
188 if let Defaultness::Default(span) = def {
189 let msg = format!("{} {} cannot be `default`", kind.article(), kind.descr());
190 self.struct_span_err(span, &msg)
191 .span_label(span, "`default` because of this")
192 .note("only associated `fn`, `const`, and `type` items can be `default`")
193 .emit();
416331ca 194 }
74b04a01 195 }
e74abb32 196
74b04a01
XL
197 /// Parses one of the items allowed by the flags.
198 fn parse_item_kind(
199 &mut self,
200 attrs: &mut Vec<Attribute>,
201 macros_allowed: bool,
202 lo: Span,
203 vis: &Visibility,
204 def: &mut Defaultness,
205 req_name: ReqName,
206 ) -> PResult<'a, Option<ItemInfo>> {
6a06907d 207 let def_final = def == &Defaultness::Final;
74b04a01 208 let mut def = || mem::replace(def, Defaultness::Final);
e74abb32 209
74b04a01
XL
210 let info = if self.eat_keyword(kw::Use) {
211 // USE ITEM
212 let tree = self.parse_use_tree()?;
5869c6ff
XL
213
214 // If wildcard or glob-like brace syntax doesn't have `;`,
215 // the user may not know `*` or `{}` should be the last.
216 if let Err(mut e) = self.expect_semi() {
217 match tree.kind {
218 UseTreeKind::Glob => {
219 e.note("the wildcard token must be last on the path").emit();
220 }
221 UseTreeKind::Nested(..) => {
222 e.note("glob-like brace syntax must be last on the path").emit();
223 }
224 _ => (),
225 }
226 return Err(e);
227 }
228
6a06907d
XL
229 (Ident::invalid(), ItemKind::Use(tree))
230 } else if self.check_fn_front_matter(def_final) {
74b04a01 231 // FUNCTION ITEM
3dfed10e 232 let (ident, sig, generics, body) = self.parse_fn(attrs, req_name, lo)?;
5869c6ff 233 (ident, ItemKind::Fn(box FnKind(def(), sig, generics, body)))
74b04a01
XL
234 } else if self.eat_keyword(kw::Extern) {
235 if self.eat_keyword(kw::Crate) {
236 // EXTERN CRATE
237 self.parse_item_extern_crate()?
238 } else {
239 // EXTERN BLOCK
1b1a35ee 240 self.parse_item_foreign_mod(attrs, Unsafe::No)?
74b04a01 241 }
1b1a35ee
XL
242 } else if self.is_unsafe_foreign_mod() {
243 // EXTERN BLOCK
244 let unsafety = self.parse_unsafety();
245 self.expect_keyword(kw::Extern)?;
246 self.parse_item_foreign_mod(attrs, unsafety)?
74b04a01
XL
247 } else if self.is_static_global() {
248 // STATIC ITEM
249 self.bump(); // `static`
250 let m = self.parse_mutability();
251 let (ident, ty, expr) = self.parse_item_global(Some(m))?;
252 (ident, ItemKind::Static(ty, m, expr))
253 } else if let Const::Yes(const_span) = self.parse_constness() {
254 // CONST ITEM
fc512014
XL
255 if self.token.is_keyword(kw::Impl) {
256 // recover from `const impl`, suggest `impl const`
257 self.recover_const_impl(const_span, attrs, def())?
258 } else {
259 self.recover_const_mut(const_span);
260 let (ident, ty, expr) = self.parse_item_global(None)?;
261 (ident, ItemKind::Const(def(), ty, expr))
262 }
74b04a01
XL
263 } else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() {
264 // TRAIT ITEM
265 self.parse_item_trait(attrs, lo)?
266 } else if self.check_keyword(kw::Impl)
dfeec247 267 || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Impl])
e74abb32 268 {
416331ca 269 // IMPL ITEM
74b04a01 270 self.parse_item_impl(attrs, def())?
1b1a35ee
XL
271 } else if self.check_keyword(kw::Mod)
272 || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Mod])
273 {
416331ca 274 // MODULE ITEM
74b04a01
XL
275 self.parse_item_mod(attrs)?
276 } else if self.eat_keyword(kw::Type) {
416331ca 277 // TYPE ITEM
74b04a01
XL
278 self.parse_type_alias(def())?
279 } else if self.eat_keyword(kw::Enum) {
416331ca 280 // ENUM ITEM
74b04a01
XL
281 self.parse_item_enum()?
282 } else if self.eat_keyword(kw::Struct) {
416331ca 283 // STRUCT ITEM
74b04a01
XL
284 self.parse_item_struct()?
285 } else if self.is_kw_followed_by_ident(kw::Union) {
416331ca 286 // UNION ITEM
74b04a01
XL
287 self.bump(); // `union`
288 self.parse_item_union()?
289 } else if self.eat_keyword(kw::Macro) {
290 // MACROS 2.0 ITEM
291 self.parse_item_decl_macro(lo)?
292 } else if self.is_macro_rules_item() {
293 // MACRO_RULES ITEM
294 self.parse_item_macro_rules(vis)?
1b1a35ee 295 } else if vis.kind.is_pub() && self.isnt_macro_invocation() {
74b04a01
XL
296 self.recover_missing_kw_before_item()?;
297 return Ok(None);
ba9703b0 298 } else if macros_allowed && self.check_path() {
74b04a01 299 // MACRO INVOCATION ITEM
ba9703b0 300 (Ident::invalid(), ItemKind::MacCall(self.parse_item_macro(vis)?))
74b04a01
XL
301 } else {
302 return Ok(None);
303 };
304 Ok(Some(info))
305 }
e74abb32 306
74b04a01
XL
307 /// When parsing a statement, would the start of a path be an item?
308 pub(super) fn is_path_start_item(&mut self) -> bool {
309 self.is_crate_vis() // no: `crate::b`, yes: `crate $item`
310 || self.is_kw_followed_by_ident(kw::Union) // no: `union::b`, yes: `union U { .. }`
311 || self.check_auto_or_unsafe_trait_item() // no: `auto::b`, yes: `auto trait X { .. }`
312 || self.is_async_fn() // no(2015): `async::b`, yes: `async fn`
313 || self.is_macro_rules_item() // no: `macro_rules::b`, yes: `macro_rules! mac`
314 }
315
316 /// Are we sure this could not possibly be a macro invocation?
317 fn isnt_macro_invocation(&mut self) -> bool {
318 self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::ModSep)
319 }
320
321 /// Recover on encountering a struct or method definition where the user
322 /// forgot to add the `struct` or `fn` keyword after writing `pub`: `pub S {}`.
323 fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
324 // Space between `pub` keyword and the identifier
325 //
326 // pub S {}
327 // ^^^ `sp` points here
328 let sp = self.prev_token.span.between(self.token.span);
329 let full_sp = self.prev_token.span.to(self.token.span);
330 let ident_sp = self.token.span;
331 if self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) {
332 // possible public struct definition where `struct` was forgotten
333 let ident = self.parse_ident().unwrap();
334 let msg = format!("add `struct` here to parse `{}` as a public struct", ident);
335 let mut err = self.struct_span_err(sp, "missing `struct` for struct definition");
336 err.span_suggestion_short(
337 sp,
338 &msg,
339 " struct ".into(),
340 Applicability::MaybeIncorrect, // speculative
341 );
ba9703b0 342 Err(err)
74b04a01
XL
343 } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
344 let ident = self.parse_ident().unwrap();
345 self.bump(); // `(`
346 let kw_name = self.recover_first_param();
347 self.consume_block(token::Paren, ConsumeClosingDelim::Yes);
348 let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
349 self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
350 self.bump(); // `{`
351 ("fn", kw_name, false)
352 } else if self.check(&token::OpenDelim(token::Brace)) {
353 self.bump(); // `{`
354 ("fn", kw_name, false)
355 } else if self.check(&token::Colon) {
356 let kw = "struct";
357 (kw, kw, false)
358 } else {
359 ("fn` or `struct", "function or struct", true)
360 };
416331ca 361
74b04a01
XL
362 let msg = format!("missing `{}` for {} definition", kw, kw_name);
363 let mut err = self.struct_span_err(sp, &msg);
364 if !ambiguous {
365 self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
366 let suggestion =
367 format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name);
416331ca 368 err.span_suggestion_short(
dfeec247 369 sp,
74b04a01
XL
370 &suggestion,
371 format!(" {} ", kw),
372 Applicability::MachineApplicable,
416331ca 373 );
29967ef6
XL
374 } else if let Ok(snippet) = self.span_to_snippet(ident_sp) {
375 err.span_suggestion(
376 full_sp,
377 "if you meant to call a macro, try",
378 format!("{}!", snippet),
379 // this is the `ambiguous` conditional branch
380 Applicability::MaybeIncorrect,
381 );
74b04a01 382 } else {
29967ef6
XL
383 err.help(
384 "if you meant to call a macro, remove the `pub` \
385 and add a trailing `!` after the identifier",
386 );
416331ca 387 }
ba9703b0 388 Err(err)
74b04a01
XL
389 } else if self.look_ahead(1, |t| *t == token::Lt) {
390 let ident = self.parse_ident().unwrap();
391 self.eat_to_tokens(&[&token::Gt]);
392 self.bump(); // `>`
393 let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
394 ("fn", self.recover_first_param(), false)
395 } else if self.check(&token::OpenDelim(token::Brace)) {
396 ("struct", "struct", false)
397 } else {
398 ("fn` or `struct", "function or struct", true)
399 };
400 let msg = format!("missing `{}` for {} definition", kw, kw_name);
401 let mut err = self.struct_span_err(sp, &msg);
402 if !ambiguous {
403 err.span_suggestion_short(
404 sp,
405 &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
406 format!(" {} ", kw),
407 Applicability::MachineApplicable,
408 );
416331ca 409 }
ba9703b0 410 Err(err)
74b04a01
XL
411 } else {
412 Ok(())
416331ca 413 }
74b04a01 414 }
416331ca 415
74b04a01 416 /// Parses an item macro, e.g., `item!();`.
ba9703b0 417 fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
74b04a01
XL
418 let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
419 self.expect(&token::Not)?; // `!`
420 let args = self.parse_mac_args()?; // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
421 self.eat_semi_for_macro_if_needed(&args);
422 self.complain_if_pub_macro(vis, false);
ba9703b0 423 Ok(MacCall { path, args, prior_type_ascription: self.last_type_ascription })
416331ca
XL
424 }
425
74b04a01
XL
426 /// Recover if we parsed attributes and expected an item but there was none.
427 fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
428 let (start, end) = match attrs {
429 [] => return Ok(()),
ba9703b0 430 [x0 @ xn] | [x0, .., xn] => (x0, xn),
416331ca 431 };
74b04a01
XL
432 let msg = if end.is_doc_comment() {
433 "expected item after doc comment"
434 } else {
435 "expected item after attributes"
436 };
437 let mut err = self.struct_span_err(end.span, msg);
438 if end.is_doc_comment() {
439 err.span_label(end.span, "this doc comment doesn't document anything");
440 }
441 if let [.., penultimate, _] = attrs {
442 err.span_label(start.span.to(penultimate.span), "other attributes here");
416331ca
XL
443 }
444 Err(err)
445 }
446
74b04a01 447 fn is_async_fn(&self) -> bool {
dfeec247 448 self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
416331ca
XL
449 }
450
ba9703b0
XL
451 fn parse_polarity(&mut self) -> ast::ImplPolarity {
452 // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
453 if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) {
454 self.bump(); // `!`
455 ast::ImplPolarity::Negative(self.prev_token.span)
456 } else {
457 ast::ImplPolarity::Positive
458 }
459 }
460
74b04a01 461 /// Parses an implementation item.
416331ca 462 ///
74b04a01
XL
463 /// ```
464 /// impl<'a, T> TYPE { /* impl items */ }
465 /// impl<'a, T> TRAIT for TYPE { /* impl items */ }
466 /// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
467 /// impl<'a, T> const TRAIT for TYPE { /* impl items */ }
468 /// ```
416331ca
XL
469 ///
470 /// We actually parse slightly more relaxed grammar for better error reporting and recovery.
74b04a01
XL
471 /// ```
472 /// "impl" GENERICS "const"? "!"? TYPE "for"? (TYPE | "..") ("where" PREDICATES)? "{" BODY "}"
473 /// "impl" GENERICS "const"? "!"? TYPE ("where" PREDICATES)? "{" BODY "}"
474 /// ```
dfeec247
XL
475 fn parse_item_impl(
476 &mut self,
74b04a01 477 attrs: &mut Vec<Attribute>,
dfeec247
XL
478 defaultness: Defaultness,
479 ) -> PResult<'a, ItemInfo> {
74b04a01
XL
480 let unsafety = self.parse_unsafety();
481 self.expect_keyword(kw::Impl)?;
482
416331ca 483 // First, parse generic parameters if necessary.
ba9703b0 484 let mut generics = if self.choose_generics_over_qpath(0) {
416331ca
XL
485 self.parse_generics()?
486 } else {
dfeec247
XL
487 let mut generics = Generics::default();
488 // impl A for B {}
489 // /\ this is where `generics.span` should point when there are no type params.
74b04a01 490 generics.span = self.prev_token.span.shrink_to_hi();
dfeec247
XL
491 generics
492 };
493
74b04a01
XL
494 let constness = self.parse_constness();
495 if let Const::Yes(span) = constness {
dfeec247 496 self.sess.gated_spans.gate(sym::const_trait_impl, span);
74b04a01 497 }
416331ca 498
ba9703b0 499 let polarity = self.parse_polarity();
416331ca
XL
500
501 // Parse both types and traits as a type, then reinterpret if necessary.
5869c6ff 502 let err_path = |span| ast::Path::from_ident(Ident::new(kw::Empty, span));
dfeec247
XL
503 let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
504 {
74b04a01 505 let span = self.prev_token.span.between(self.token.span);
416331ca 506 self.struct_span_err(span, "missing trait in a trait impl").emit();
1b1a35ee
XL
507 P(Ty {
508 kind: TyKind::Path(None, err_path(span)),
509 span,
510 id: DUMMY_NODE_ID,
511 tokens: None,
512 })
416331ca
XL
513 } else {
514 self.parse_ty()?
515 };
516
517 // If `for` is missing we try to recover.
518 let has_for = self.eat_keyword(kw::For);
74b04a01 519 let missing_for_span = self.prev_token.span.between(self.token.span);
416331ca
XL
520
521 let ty_second = if self.token == token::DotDot {
522 // We need to report this error after `cfg` expansion for compatibility reasons
523 self.bump(); // `..`, do not add it to expected tokens
74b04a01 524 Some(self.mk_ty(self.prev_token.span, TyKind::Err))
416331ca
XL
525 } else if has_for || self.token.can_begin_type() {
526 Some(self.parse_ty()?)
527 } else {
528 None
529 };
530
531 generics.where_clause = self.parse_where_clause()?;
532
74b04a01 533 let impl_items = self.parse_item_list(attrs, |p| p.parse_impl_item())?;
416331ca
XL
534
535 let item_kind = match ty_second {
536 Some(ty_second) => {
537 // impl Trait for Type
538 if !has_for {
539 self.struct_span_err(missing_for_span, "missing `for` in a trait impl")
540 .span_suggestion_short(
541 missing_for_span,
542 "add `for` here",
543 " for ".to_string(),
544 Applicability::MachineApplicable,
dfeec247
XL
545 )
546 .emit();
416331ca
XL
547 }
548
549 let ty_first = ty_first.into_inner();
e74abb32 550 let path = match ty_first.kind {
416331ca
XL
551 // This notably includes paths passed through `ty` macro fragments (#46438).
552 TyKind::Path(None, path) => path,
553 _ => {
dfeec247 554 self.struct_span_err(ty_first.span, "expected a trait, found type").emit();
416331ca
XL
555 err_path(ty_first.span)
556 }
557 };
558 let trait_ref = TraitRef { path, ref_id: ty_first.id };
559
5869c6ff 560 ItemKind::Impl(box ImplKind {
dfeec247
XL
561 unsafety,
562 polarity,
563 defaultness,
564 constness,
565 generics,
566 of_trait: Some(trait_ref),
567 self_ty: ty_second,
568 items: impl_items,
5869c6ff 569 })
416331ca
XL
570 }
571 None => {
572 // impl Type
5869c6ff 573 ItemKind::Impl(box ImplKind {
dfeec247
XL
574 unsafety,
575 polarity,
576 defaultness,
577 constness,
578 generics,
579 of_trait: None,
580 self_ty: ty_first,
581 items: impl_items,
5869c6ff 582 })
416331ca
XL
583 }
584 };
585
74b04a01 586 Ok((Ident::invalid(), item_kind))
416331ca
XL
587 }
588
74b04a01
XL
589 fn parse_item_list<T>(
590 &mut self,
591 attrs: &mut Vec<Attribute>,
592 mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
593 ) -> PResult<'a, Vec<T>> {
594 let open_brace_span = self.token.span;
416331ca 595 self.expect(&token::OpenDelim(token::Brace))?;
74b04a01 596 attrs.append(&mut self.parse_inner_attributes()?);
416331ca 597
74b04a01 598 let mut items = Vec::new();
416331ca 599 while !self.eat(&token::CloseDelim(token::Brace)) {
74b04a01
XL
600 if self.recover_doc_comment_before_brace() {
601 continue;
602 }
603 match parse_item(self) {
604 Ok(None) => {
605 // We have to bail or we'll potentially never make progress.
606 let non_item_span = self.token.span;
607 self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
608 self.struct_span_err(non_item_span, "non-item in item list")
609 .span_label(open_brace_span, "item list starts here")
610 .span_label(non_item_span, "non-item starts here")
611 .span_label(self.prev_token.span, "item list ends here")
612 .emit();
613 break;
614 }
615 Ok(Some(item)) => items.extend(item),
416331ca 616 Err(mut err) => {
74b04a01
XL
617 self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
618 err.span_label(open_brace_span, "while parsing this item list starting here")
619 .span_label(self.prev_token.span, "the item list ends here")
620 .emit();
621 break;
416331ca
XL
622 }
623 }
624 }
74b04a01
XL
625 Ok(items)
626 }
627
628 /// Recover on a doc comment before `}`.
629 fn recover_doc_comment_before_brace(&mut self) -> bool {
3dfed10e 630 if let token::DocComment(..) = self.token.kind {
74b04a01
XL
631 if self.look_ahead(1, |tok| tok == &token::CloseDelim(token::Brace)) {
632 struct_span_err!(
633 self.diagnostic(),
634 self.token.span,
635 E0584,
636 "found a documentation comment that doesn't document anything",
637 )
638 .span_label(self.token.span, "this doc comment doesn't document anything")
639 .help(
640 "doc comments must come before what they document, maybe a \
641 comment was intended with `//`?",
642 )
643 .emit();
644 self.bump();
645 return true;
646 }
647 }
648 false
416331ca
XL
649 }
650
416331ca
XL
651 /// Parses defaultness (i.e., `default` or nothing).
652 fn parse_defaultness(&mut self) -> Defaultness {
74b04a01
XL
653 // We are interested in `default` followed by another identifier.
654 // However, we must avoid keywords that occur as binary operators.
655 // Currently, the only applicable keyword is `as` (`default as Ty`).
dfeec247 656 if self.check_keyword(kw::Default)
74b04a01 657 && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
416331ca
XL
658 {
659 self.bump(); // `default`
74b04a01 660 Defaultness::Default(self.prev_token.uninterpolated_span())
416331ca
XL
661 } else {
662 Defaultness::Final
663 }
664 }
665
74b04a01
XL
666 /// Is this an `(unsafe auto? | auto) trait` item?
667 fn check_auto_or_unsafe_trait_item(&mut self) -> bool {
668 // auto trait
669 self.check_keyword(kw::Auto) && self.is_keyword_ahead(1, &[kw::Trait])
670 // unsafe auto trait
671 || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
672 }
673
674 /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
675 fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<'a, ItemInfo> {
676 let unsafety = self.parse_unsafety();
e74abb32 677 // Parse optional `auto` prefix.
dfeec247 678 let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No };
416331ca 679
e74abb32 680 self.expect_keyword(kw::Trait)?;
416331ca
XL
681 let ident = self.parse_ident()?;
682 let mut tps = self.parse_generics()?;
683
684 // Parse optional colon and supertrait bounds.
e74abb32 685 let had_colon = self.eat(&token::Colon);
74b04a01
XL
686 let span_at_colon = self.prev_token.span;
687 let bounds = if had_colon {
688 self.parse_generic_bounds(Some(self.prev_token.span))?
689 } else {
690 Vec::new()
691 };
416331ca 692
74b04a01 693 let span_before_eq = self.prev_token.span;
416331ca 694 if self.eat(&token::Eq) {
e1599b0c 695 // It's a trait alias.
e74abb32
XL
696 if had_colon {
697 let span = span_at_colon.to(span_before_eq);
dfeec247 698 self.struct_span_err(span, "bounds are not allowed on trait aliases").emit();
e74abb32
XL
699 }
700
416331ca
XL
701 let bounds = self.parse_generic_bounds(None)?;
702 tps.where_clause = self.parse_where_clause()?;
e74abb32
XL
703 self.expect_semi()?;
704
74b04a01 705 let whole_span = lo.to(self.prev_token.span);
416331ca
XL
706 if is_auto == IsAuto::Yes {
707 let msg = "trait aliases cannot be `auto`";
dfeec247 708 self.struct_span_err(whole_span, msg).span_label(whole_span, msg).emit();
416331ca 709 }
74b04a01 710 if let Unsafe::Yes(_) = unsafety {
416331ca 711 let msg = "trait aliases cannot be `unsafe`";
dfeec247 712 self.struct_span_err(whole_span, msg).span_label(whole_span, msg).emit();
416331ca 713 }
e74abb32 714
60c5eb7d 715 self.sess.gated_spans.gate(sym::trait_alias, whole_span);
e74abb32 716
74b04a01 717 Ok((ident, ItemKind::TraitAlias(tps, bounds)))
416331ca 718 } else {
e1599b0c 719 // It's a normal trait.
416331ca 720 tps.where_clause = self.parse_where_clause()?;
74b04a01 721 let items = self.parse_item_list(attrs, |p| p.parse_trait_item())?;
5869c6ff 722 Ok((ident, ItemKind::Trait(box TraitKind(is_auto, unsafety, tps, bounds, items))))
416331ca
XL
723 }
724 }
725
74b04a01
XL
726 pub fn parse_impl_item(&mut self) -> PResult<'a, Option<Option<P<AssocItem>>>> {
727 self.parse_assoc_item(|_| true)
dfeec247
XL
728 }
729
74b04a01
XL
730 pub fn parse_trait_item(&mut self) -> PResult<'a, Option<Option<P<AssocItem>>>> {
731 self.parse_assoc_item(|edition| edition >= Edition::Edition2018)
dfeec247
XL
732 }
733
734 /// Parses associated items.
74b04a01 735 fn parse_assoc_item(&mut self, req_name: ReqName) -> PResult<'a, Option<Option<P<AssocItem>>>> {
5869c6ff
XL
736 Ok(self.parse_item_(req_name, ForceCollect::No)?.map(
737 |Item { attrs, id, span, vis, ident, kind, tokens }| {
738 let kind = match AssocItemKind::try_from(kind) {
739 Ok(kind) => kind,
740 Err(kind) => match kind {
741 ItemKind::Static(a, _, b) => {
742 self.struct_span_err(span, "associated `static` items are not allowed")
743 .emit();
744 AssocItemKind::Const(Defaultness::Final, a, b)
745 }
746 _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
747 },
748 };
749 Some(P(Item { attrs, id, span, vis, ident, kind, tokens }))
750 },
751 ))
e74abb32
XL
752 }
753
74b04a01
XL
754 /// Parses a `type` alias with the following grammar:
755 /// ```
756 /// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
757 /// ```
758 /// The `"type"` has already been eaten.
759 fn parse_type_alias(&mut self, def: Defaultness) -> PResult<'a, ItemInfo> {
416331ca
XL
760 let ident = self.parse_ident()?;
761 let mut generics = self.parse_generics()?;
762
763 // Parse optional colon and param bounds.
dfeec247
XL
764 let bounds =
765 if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
416331ca
XL
766 generics.where_clause = self.parse_where_clause()?;
767
dfeec247 768 let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
e74abb32 769 self.expect_semi()?;
416331ca 770
5869c6ff 771 Ok((ident, ItemKind::TyAlias(box TyAliasKind(def, generics, bounds, default))))
416331ca
XL
772 }
773
774 /// Parses a `UseTree`.
775 ///
ba9703b0 776 /// ```text
416331ca
XL
777 /// USE_TREE = [`::`] `*` |
778 /// [`::`] `{` USE_TREE_LIST `}` |
779 /// PATH `::` `*` |
780 /// PATH `::` `{` USE_TREE_LIST `}` |
781 /// PATH [`as` IDENT]
782 /// ```
783 fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
784 let lo = self.token.span;
785
1b1a35ee 786 let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo(), tokens: None };
dfeec247
XL
787 let kind = if self.check(&token::OpenDelim(token::Brace))
788 || self.check(&token::BinOp(token::Star))
789 || self.is_import_coupler()
790 {
416331ca
XL
791 // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
792 let mod_sep_ctxt = self.token.span.ctxt();
793 if self.eat(&token::ModSep) {
dfeec247
XL
794 prefix
795 .segments
796 .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
416331ca
XL
797 }
798
e74abb32 799 self.parse_use_tree_glob_or_nested()?
416331ca
XL
800 } else {
801 // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
802 prefix = self.parse_path(PathStyle::Mod)?;
803
804 if self.eat(&token::ModSep) {
e74abb32 805 self.parse_use_tree_glob_or_nested()?
416331ca 806 } else {
e1599b0c 807 UseTreeKind::Simple(self.parse_rename()?, DUMMY_NODE_ID, DUMMY_NODE_ID)
416331ca
XL
808 }
809 };
810
74b04a01 811 Ok(UseTree { prefix, kind, span: lo.to(self.prev_token.span) })
416331ca
XL
812 }
813
e74abb32
XL
814 /// Parses `*` or `{...}`.
815 fn parse_use_tree_glob_or_nested(&mut self) -> PResult<'a, UseTreeKind> {
816 Ok(if self.eat(&token::BinOp(token::Star)) {
817 UseTreeKind::Glob
818 } else {
819 UseTreeKind::Nested(self.parse_use_tree_list()?)
820 })
821 }
822
416331ca
XL
823 /// Parses a `UseTreeKind::Nested(list)`.
824 ///
ba9703b0 825 /// ```text
416331ca
XL
826 /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
827 /// ```
828 fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
e1599b0c 829 self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, DUMMY_NODE_ID)))
416331ca
XL
830 .map(|(r, _)| r)
831 }
832
833 fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
dfeec247 834 if self.eat_keyword(kw::As) { self.parse_ident_or_underscore().map(Some) } else { Ok(None) }
416331ca
XL
835 }
836
f9f354fc 837 fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
74b04a01
XL
838 match self.token.ident() {
839 Some((ident @ Ident { name: kw::Underscore, .. }, false)) => {
416331ca 840 self.bump();
74b04a01 841 Ok(ident)
416331ca
XL
842 }
843 _ => self.parse_ident(),
844 }
845 }
846
847 /// Parses `extern crate` links.
848 ///
849 /// # Examples
850 ///
851 /// ```
852 /// extern crate foo;
853 /// extern crate bar as foo;
854 /// ```
74b04a01 855 fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemInfo> {
416331ca
XL
856 // Accept `extern crate name-like-this` for better diagnostics
857 let orig_name = self.parse_crate_name_with_dashes()?;
858 let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
859 (rename, Some(orig_name.name))
860 } else {
861 (orig_name, None)
862 };
e74abb32 863 self.expect_semi()?;
74b04a01 864 Ok((item_name, ItemKind::ExternCrate(orig_name)))
416331ca
XL
865 }
866
f9f354fc 867 fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
416331ca
XL
868 let error_msg = "crate name using dashes are not valid in `extern crate` statements";
869 let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
870 in the code";
871 let mut ident = if self.token.is_keyword(kw::SelfLower) {
872 self.parse_path_segment_ident()
873 } else {
874 self.parse_ident()
875 }?;
876 let mut idents = vec![];
877 let mut replacement = vec![];
878 let mut fixed_crate_name = false;
e1599b0c 879 // Accept `extern crate name-like-this` for better diagnostics.
416331ca 880 let dash = token::BinOp(token::BinOpToken::Minus);
dfeec247
XL
881 if self.token == dash {
882 // Do not include `-` as part of the expected tokens list.
416331ca
XL
883 while self.eat(&dash) {
884 fixed_crate_name = true;
74b04a01 885 replacement.push((self.prev_token.span, "_".to_string()));
416331ca
XL
886 idents.push(self.parse_ident()?);
887 }
888 }
889 if fixed_crate_name {
890 let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
891 let mut fixed_name = format!("{}", ident.name);
892 for part in idents {
893 fixed_name.push_str(&format!("_{}", part.name));
894 }
e1599b0c 895 ident = Ident::from_str_and_span(&fixed_name, fixed_name_sp);
416331ca
XL
896
897 self.struct_span_err(fixed_name_sp, error_msg)
898 .span_label(fixed_name_sp, "dash-separated idents are not valid")
899 .multipart_suggestion(suggestion_msg, replacement, Applicability::MachineApplicable)
900 .emit();
901 }
902 Ok(ident)
903 }
904
416331ca
XL
905 /// Parses `extern` for foreign ABIs modules.
906 ///
74b04a01 907 /// `extern` is expected to have been consumed before calling this method.
416331ca
XL
908 ///
909 /// # Examples
910 ///
911 /// ```ignore (only-for-syntax-highlight)
912 /// extern "C" {}
913 /// extern {}
914 /// ```
1b1a35ee
XL
915 fn parse_item_foreign_mod(
916 &mut self,
917 attrs: &mut Vec<Attribute>,
918 unsafety: Unsafe,
919 ) -> PResult<'a, ItemInfo> {
74b04a01
XL
920 let abi = self.parse_abi(); // ABI?
921 let items = self.parse_item_list(attrs, |p| p.parse_foreign_item())?;
1b1a35ee 922 let module = ast::ForeignMod { unsafety, abi, items };
74b04a01 923 Ok((Ident::invalid(), ItemKind::ForeignMod(module)))
416331ca
XL
924 }
925
74b04a01
XL
926 /// Parses a foreign item (one in an `extern { ... }` block).
927 pub fn parse_foreign_item(&mut self) -> PResult<'a, Option<Option<P<ForeignItem>>>> {
5869c6ff
XL
928 Ok(self.parse_item_(|_| true, ForceCollect::No)?.map(
929 |Item { attrs, id, span, vis, ident, kind, tokens }| {
930 let kind = match ForeignItemKind::try_from(kind) {
931 Ok(kind) => kind,
932 Err(kind) => match kind {
933 ItemKind::Const(_, a, b) => {
934 self.error_on_foreign_const(span, ident);
935 ForeignItemKind::Static(a, Mutability::Not, b)
936 }
937 _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
938 },
939 };
940 Some(P(Item { attrs, id, span, vis, ident, kind, tokens }))
941 },
942 ))
416331ca
XL
943 }
944
74b04a01 945 fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &str) -> Option<T> {
ba9703b0
XL
946 let span = self.sess.source_map().guess_head_span(span);
947 let descr = kind.descr();
948 self.struct_span_err(span, &format!("{} is not supported in {}", descr, ctx))
949 .help(&format!("consider moving the {} out to a nearby module scope", descr))
950 .emit();
951 None
416331ca
XL
952 }
953
74b04a01
XL
954 fn error_on_foreign_const(&self, span: Span, ident: Ident) {
955 self.struct_span_err(ident.span, "extern items cannot be `const`")
956 .span_suggestion(
957 span.with_hi(ident.span.lo()),
958 "try using a static value",
959 "static ".to_string(),
960 Applicability::MachineApplicable,
961 )
962 .note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")
963 .emit();
416331ca
XL
964 }
965
1b1a35ee
XL
966 fn is_unsafe_foreign_mod(&self) -> bool {
967 self.token.is_keyword(kw::Unsafe)
968 && self.is_keyword_ahead(1, &[kw::Extern])
969 && self.look_ahead(
970 2 + self.look_ahead(2, |t| t.can_begin_literal_maybe_minus() as usize),
971 |t| t.kind == token::OpenDelim(token::Brace),
972 )
973 }
974
416331ca
XL
975 fn is_static_global(&mut self) -> bool {
976 if self.check_keyword(kw::Static) {
e1599b0c 977 // Check if this could be a closure.
416331ca
XL
978 !self.look_ahead(1, |token| {
979 if token.is_keyword(kw::Move) {
980 return true;
981 }
29967ef6 982 matches!(token.kind, token::BinOp(token::Or) | token::OrOr)
416331ca
XL
983 })
984 } else {
985 false
986 }
987 }
988
74b04a01
XL
989 /// Recover on `const mut` with `const` already eaten.
990 fn recover_const_mut(&mut self, const_span: Span) {
991 if self.eat_keyword(kw::Mut) {
992 let span = self.prev_token.span;
993 self.struct_span_err(span, "const globals cannot be mutable")
994 .span_label(span, "cannot be mutable")
995 .span_suggestion(
996 const_span,
997 "you might want to declare a static instead",
998 "static".to_owned(),
999 Applicability::MaybeIncorrect,
1000 )
1001 .emit();
1002 }
1003 }
1004
fc512014
XL
1005 /// Recover on `const impl` with `const` already eaten.
1006 fn recover_const_impl(
1007 &mut self,
1008 const_span: Span,
1009 attrs: &mut Vec<Attribute>,
1010 defaultness: Defaultness,
1011 ) -> PResult<'a, ItemInfo> {
1012 let impl_span = self.token.span;
1013 let mut err = self.expected_ident_found();
5869c6ff
XL
1014
1015 // Only try to recover if this is implementing a trait for a type
1016 let mut impl_info = match self.parse_item_impl(attrs, defaultness) {
1017 Ok(impl_info) => impl_info,
1018 Err(mut recovery_error) => {
1019 // Recovery failed, raise the "expected identifier" error
1020 recovery_error.cancel();
1021 return Err(err);
1022 }
1023 };
1024
fc512014 1025 match impl_info.1 {
5869c6ff
XL
1026 ItemKind::Impl(box ImplKind {
1027 of_trait: Some(ref trai), ref mut constness, ..
1028 }) => {
fc512014
XL
1029 *constness = Const::Yes(const_span);
1030
1031 let before_trait = trai.path.span.shrink_to_lo();
1032 let const_up_to_impl = const_span.with_hi(impl_span.lo());
1033 err.multipart_suggestion(
1034 "you might have meant to write a const trait impl",
1035 vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())],
1036 Applicability::MaybeIncorrect,
1037 )
1038 .emit();
1039 }
1040 ItemKind::Impl { .. } => return Err(err),
1041 _ => unreachable!(),
1042 }
5869c6ff 1043
fc512014
XL
1044 Ok(impl_info)
1045 }
1046
74b04a01 1047 /// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with
e74abb32
XL
1048 /// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
1049 ///
1050 /// When `m` is `"const"`, `$ident` may also be `"_"`.
74b04a01
XL
1051 fn parse_item_global(
1052 &mut self,
1053 m: Option<Mutability>,
1054 ) -> PResult<'a, (Ident, P<Ty>, Option<P<ast::Expr>>)> {
416331ca 1055 let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
e74abb32
XL
1056
1057 // Parse the type of a `const` or `static mut?` item.
1058 // That is, the `":" $ty` fragment.
74b04a01 1059 let ty = if self.eat(&token::Colon) {
e74abb32 1060 self.parse_ty()?
74b04a01
XL
1061 } else {
1062 self.recover_missing_const_type(id, m)
e74abb32
XL
1063 };
1064
74b04a01 1065 let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None };
e74abb32 1066 self.expect_semi()?;
74b04a01 1067 Ok((id, ty, expr))
416331ca
XL
1068 }
1069
74b04a01 1070 /// We were supposed to parse `:` but the `:` was missing.
e74abb32
XL
1071 /// This means that the type is missing.
1072 fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
1073 // Construct the error and stash it away with the hope
1074 // that typeck will later enrich the error with a type.
1075 let kind = match m {
dfeec247
XL
1076 Some(Mutability::Mut) => "static mut",
1077 Some(Mutability::Not) => "static",
e74abb32
XL
1078 None => "const",
1079 };
1080 let mut err = self.struct_span_err(id.span, &format!("missing type for `{}` item", kind));
1081 err.span_suggestion(
1082 id.span,
1083 "provide a type for the item",
1084 format!("{}: <type>", id),
1085 Applicability::HasPlaceholders,
1086 );
1087 err.stash(id.span, StashKey::ItemNoType);
1088
1089 // The user intended that the type be inferred,
1090 // so treat this as if the user wrote e.g. `const A: _ = expr;`.
1b1a35ee 1091 P(Ty { kind: TyKind::Infer, span: id.span, id: ast::DUMMY_NODE_ID, tokens: None })
e74abb32
XL
1092 }
1093
416331ca
XL
1094 /// Parses an enum declaration.
1095 fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
1096 let id = self.parse_ident()?;
1097 let mut generics = self.parse_generics()?;
1098 generics.where_clause = self.parse_where_clause()?;
416331ca 1099
dfeec247
XL
1100 let (variants, _) =
1101 self.parse_delim_comma_seq(token::Brace, |p| p.parse_enum_variant()).map_err(|e| {
1102 self.recover_stmt();
1103 e
1104 })?;
60c5eb7d 1105
dfeec247
XL
1106 let enum_definition =
1107 EnumDef { variants: variants.into_iter().filter_map(|v| v).collect() };
74b04a01 1108 Ok((id, ItemKind::Enum(enum_definition, generics)))
416331ca
XL
1109 }
1110
60c5eb7d
XL
1111 fn parse_enum_variant(&mut self) -> PResult<'a, Option<Variant>> {
1112 let variant_attrs = self.parse_outer_attributes()?;
6a06907d
XL
1113 self.collect_tokens_trailing_token(
1114 variant_attrs,
1115 ForceCollect::No,
1116 |this, variant_attrs| {
1117 let vlo = this.token.span;
1118
1119 let vis = this.parse_visibility(FollowedByType::No)?;
1120 if !this.recover_nested_adt_item(kw::Enum)? {
1121 return Ok((None, TrailingToken::None));
1122 }
1123 let ident = this.parse_ident()?;
1124
1125 let struct_def = if this.check(&token::OpenDelim(token::Brace)) {
1126 // Parse a struct variant.
1127 let (fields, recovered) = this.parse_record_struct_body()?;
1128 VariantData::Struct(fields, recovered)
1129 } else if this.check(&token::OpenDelim(token::Paren)) {
1130 VariantData::Tuple(this.parse_tuple_struct_body()?, DUMMY_NODE_ID)
1131 } else {
1132 VariantData::Unit(DUMMY_NODE_ID)
1133 };
416331ca 1134
6a06907d
XL
1135 let disr_expr =
1136 if this.eat(&token::Eq) { Some(this.parse_anon_const_expr()?) } else { None };
1137
1138 let vr = ast::Variant {
1139 ident,
1140 vis,
1141 id: DUMMY_NODE_ID,
1142 attrs: variant_attrs,
1143 data: struct_def,
1144 disr_expr,
1145 span: vlo.to(this.prev_token.span),
1146 is_placeholder: false,
1147 };
416331ca 1148
6a06907d
XL
1149 Ok((Some(vr), TrailingToken::MaybeComma))
1150 },
1151 )
416331ca
XL
1152 }
1153
1154 /// Parses `struct Foo { ... }`.
1155 fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
1156 let class_name = self.parse_ident()?;
1157
1158 let mut generics = self.parse_generics()?;
1159
1160 // There is a special case worth noting here, as reported in issue #17904.
1161 // If we are parsing a tuple struct it is the case that the where clause
1162 // should follow the field list. Like so:
1163 //
1164 // struct Foo<T>(T) where T: Copy;
1165 //
1166 // If we are parsing a normal record-style struct it is the case
1167 // that the where clause comes before the body, and after the generics.
1168 // So if we look ahead and see a brace or a where-clause we begin
1169 // parsing a record style struct.
1170 //
1171 // Otherwise if we look ahead and see a paren we parse a tuple-style
1172 // struct.
1173
1174 let vdata = if self.token.is_keyword(kw::Where) {
1175 generics.where_clause = self.parse_where_clause()?;
1176 if self.eat(&token::Semi) {
1177 // If we see a: `struct Foo<T> where T: Copy;` style decl.
e1599b0c 1178 VariantData::Unit(DUMMY_NODE_ID)
416331ca
XL
1179 } else {
1180 // If we see: `struct Foo<T> where T: Copy { ... }`
1181 let (fields, recovered) = self.parse_record_struct_body()?;
1182 VariantData::Struct(fields, recovered)
1183 }
1184 // No `where` so: `struct Foo<T>;`
1185 } else if self.eat(&token::Semi) {
e1599b0c 1186 VariantData::Unit(DUMMY_NODE_ID)
416331ca
XL
1187 // Record-style struct definition
1188 } else if self.token == token::OpenDelim(token::Brace) {
1189 let (fields, recovered) = self.parse_record_struct_body()?;
1190 VariantData::Struct(fields, recovered)
1191 // Tuple-style struct definition with optional where-clause.
1192 } else if self.token == token::OpenDelim(token::Paren) {
e1599b0c 1193 let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
416331ca 1194 generics.where_clause = self.parse_where_clause()?;
e74abb32 1195 self.expect_semi()?;
416331ca
XL
1196 body
1197 } else {
dfeec247
XL
1198 let token_str = super::token_descr(&self.token);
1199 let msg = &format!(
416331ca
XL
1200 "expected `where`, `{{`, `(`, or `;` after struct name, found {}",
1201 token_str
dfeec247
XL
1202 );
1203 let mut err = self.struct_span_err(self.token.span, msg);
416331ca
XL
1204 err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name");
1205 return Err(err);
1206 };
1207
74b04a01 1208 Ok((class_name, ItemKind::Struct(vdata, generics)))
416331ca
XL
1209 }
1210
1211 /// Parses `union Foo { ... }`.
1212 fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
1213 let class_name = self.parse_ident()?;
1214
1215 let mut generics = self.parse_generics()?;
1216
1217 let vdata = if self.token.is_keyword(kw::Where) {
1218 generics.where_clause = self.parse_where_clause()?;
1219 let (fields, recovered) = self.parse_record_struct_body()?;
1220 VariantData::Struct(fields, recovered)
1221 } else if self.token == token::OpenDelim(token::Brace) {
1222 let (fields, recovered) = self.parse_record_struct_body()?;
1223 VariantData::Struct(fields, recovered)
1224 } else {
dfeec247
XL
1225 let token_str = super::token_descr(&self.token);
1226 let msg = &format!("expected `where` or `{{` after union name, found {}", token_str);
1227 let mut err = self.struct_span_err(self.token.span, msg);
416331ca
XL
1228 err.span_label(self.token.span, "expected `where` or `{` after union name");
1229 return Err(err);
1230 };
1231
74b04a01 1232 Ok((class_name, ItemKind::Union(vdata, generics)))
416331ca
XL
1233 }
1234
6a06907d 1235 fn parse_record_struct_body(&mut self) -> PResult<'a, (Vec<FieldDef>, /* recovered */ bool)> {
416331ca
XL
1236 let mut fields = Vec::new();
1237 let mut recovered = false;
1238 if self.eat(&token::OpenDelim(token::Brace)) {
1239 while self.token != token::CloseDelim(token::Brace) {
6a06907d 1240 let field = self.parse_field_def().map_err(|e| {
e74abb32 1241 self.consume_block(token::Brace, ConsumeClosingDelim::No);
416331ca
XL
1242 recovered = true;
1243 e
1244 });
1245 match field {
1246 Ok(field) => fields.push(field),
1247 Err(mut err) => {
1248 err.emit();
e74abb32 1249 break;
416331ca
XL
1250 }
1251 }
1252 }
1253 self.eat(&token::CloseDelim(token::Brace));
1254 } else {
dfeec247
XL
1255 let token_str = super::token_descr(&self.token);
1256 let msg = &format!("expected `where`, or `{{` after struct name, found {}", token_str);
1257 let mut err = self.struct_span_err(self.token.span, msg);
416331ca
XL
1258 err.span_label(self.token.span, "expected `where`, or `{` after struct name");
1259 return Err(err);
1260 }
1261
1262 Ok((fields, recovered))
1263 }
1264
6a06907d 1265 fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<FieldDef>> {
416331ca
XL
1266 // This is the case where we find `struct Foo<T>(T) where T: Copy;`
1267 // Unit like structs are handled in parse_item_struct function
1268 self.parse_paren_comma_seq(|p| {
1269 let attrs = p.parse_outer_attributes()?;
6a06907d
XL
1270 p.collect_tokens_trailing_token(attrs, ForceCollect::No, |p, attrs| {
1271 let lo = p.token.span;
1272 let vis = p.parse_visibility(FollowedByType::Yes)?;
1273 let ty = p.parse_ty()?;
1274
1275 Ok((
1276 FieldDef {
1277 span: lo.to(ty.span),
1278 vis,
1279 ident: None,
1280 id: DUMMY_NODE_ID,
1281 ty,
1282 attrs,
1283 is_placeholder: false,
1284 },
1285 TrailingToken::MaybeComma,
1286 ))
416331ca 1287 })
dfeec247
XL
1288 })
1289 .map(|(r, _)| r)
416331ca
XL
1290 }
1291
1292 /// Parses an element of a struct declaration.
6a06907d 1293 fn parse_field_def(&mut self) -> PResult<'a, FieldDef> {
416331ca 1294 let attrs = self.parse_outer_attributes()?;
6a06907d
XL
1295 self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
1296 let lo = this.token.span;
1297 let vis = this.parse_visibility(FollowedByType::No)?;
1298 Ok((this.parse_single_struct_field(lo, vis, attrs)?, TrailingToken::None))
1299 })
416331ca
XL
1300 }
1301
1302 /// Parses a structure field declaration.
dfeec247
XL
1303 fn parse_single_struct_field(
1304 &mut self,
1305 lo: Span,
1306 vis: Visibility,
1307 attrs: Vec<Attribute>,
6a06907d 1308 ) -> PResult<'a, FieldDef> {
416331ca
XL
1309 let mut seen_comma: bool = false;
1310 let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
1311 if self.token == token::Comma {
1312 seen_comma = true;
1313 }
1314 match self.token.kind {
1315 token::Comma => {
1316 self.bump();
1317 }
1318 token::CloseDelim(token::Brace) => {}
3dfed10e 1319 token::DocComment(..) => {
74b04a01 1320 let previous_span = self.prev_token.span;
416331ca
XL
1321 let mut err = self.span_fatal_err(self.token.span, Error::UselessDocComment);
1322 self.bump(); // consume the doc comment
1323 let comma_after_doc_seen = self.eat(&token::Comma);
1324 // `seen_comma` is always false, because we are inside doc block
1325 // condition is here to make code more readable
74b04a01 1326 if !seen_comma && comma_after_doc_seen {
416331ca
XL
1327 seen_comma = true;
1328 }
1329 if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) {
1330 err.emit();
1331 } else {
74b04a01 1332 if !seen_comma {
416331ca
XL
1333 let sp = self.sess.source_map().next_point(previous_span);
1334 err.span_suggestion(
1335 sp,
1336 "missing comma here",
1337 ",".into(),
dfeec247 1338 Applicability::MachineApplicable,
416331ca
XL
1339 );
1340 }
1341 return Err(err);
1342 }
1343 }
1344 _ => {
74b04a01 1345 let sp = self.prev_token.span.shrink_to_hi();
dfeec247
XL
1346 let mut err = self.struct_span_err(
1347 sp,
1348 &format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
1349 );
f035d41b
XL
1350
1351 // Try to recover extra trailing angle brackets
1352 let mut recovered = false;
1353 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind {
1354 if let Some(last_segment) = segments.last() {
1355 recovered = self.check_trailing_angle_brackets(
1356 last_segment,
1357 &[&token::Comma, &token::CloseDelim(token::Brace)],
1358 );
1359 if recovered {
1360 // Handle a case like `Vec<u8>>,` where we can continue parsing fields
1361 // after the comma
1362 self.eat(&token::Comma);
1363 // `check_trailing_angle_brackets` already emitted a nicer error
1364 err.cancel();
1365 }
1366 }
1367 }
1368
416331ca
XL
1369 if self.token.is_ident() {
1370 // This is likely another field; emit the diagnostic and keep going
1371 err.span_suggestion(
1372 sp,
1373 "try adding a comma",
1374 ",".into(),
1375 Applicability::MachineApplicable,
1376 );
1377 err.emit();
f035d41b
XL
1378 recovered = true;
1379 }
1380
1381 if recovered {
1382 // Make sure an error was emitted (either by recovering an angle bracket,
1383 // or by finding an identifier as the next token), since we're
1384 // going to continue parsing
1385 assert!(self.sess.span_diagnostic.has_errors());
416331ca 1386 } else {
dfeec247 1387 return Err(err);
416331ca
XL
1388 }
1389 }
1390 }
1391 Ok(a_var)
1392 }
1393
1394 /// Parses a structure field.
1395 fn parse_name_and_ty(
1396 &mut self,
1397 lo: Span,
1398 vis: Visibility,
dfeec247 1399 attrs: Vec<Attribute>,
6a06907d 1400 ) -> PResult<'a, FieldDef> {
3dfed10e 1401 let name = self.parse_ident_common(false)?;
416331ca
XL
1402 self.expect(&token::Colon)?;
1403 let ty = self.parse_ty()?;
6a06907d 1404 Ok(FieldDef {
74b04a01 1405 span: lo.to(self.prev_token.span),
416331ca
XL
1406 ident: Some(name),
1407 vis,
e1599b0c 1408 id: DUMMY_NODE_ID,
416331ca
XL
1409 ty,
1410 attrs,
e1599b0c 1411 is_placeholder: false,
416331ca
XL
1412 })
1413 }
1414
74b04a01
XL
1415 /// Parses a declarative macro 2.0 definition.
1416 /// The `macro` keyword has already been parsed.
1417 /// ```
1418 /// MacBody = "{" TOKEN_STREAM "}" ;
1419 /// MacParams = "(" TOKEN_STREAM ")" ;
1420 /// DeclMac = "macro" Ident MacParams? MacBody ;
1421 /// ```
1422 fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> {
1423 let ident = self.parse_ident()?;
1424 let body = if self.check(&token::OpenDelim(token::Brace)) {
1425 self.parse_mac_args()? // `MacBody`
1426 } else if self.check(&token::OpenDelim(token::Paren)) {
1427 let params = self.parse_token_tree(); // `MacParams`
1428 let pspan = params.span();
1429 if !self.check(&token::OpenDelim(token::Brace)) {
60c5eb7d 1430 return self.unexpected();
74b04a01
XL
1431 }
1432 let body = self.parse_token_tree(); // `MacBody`
1433 // Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
1434 let bspan = body.span();
1435 let arrow = TokenTree::token(token::FatArrow, pspan.between(bspan)); // `=>`
1436 let tokens = TokenStream::new(vec![params.into(), arrow.into(), body.into()]);
1437 let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
1438 P(MacArgs::Delimited(dspan, MacDelimiter::Brace, tokens))
1439 } else {
1440 return self.unexpected();
1441 };
1442
1443 self.sess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
ba9703b0 1444 Ok((ident, ItemKind::MacroDef(ast::MacroDef { body, macro_rules: false })))
74b04a01 1445 }
416331ca 1446
74b04a01
XL
1447 /// Is this unambiguously the start of a `macro_rules! foo` item defnition?
1448 fn is_macro_rules_item(&mut self) -> bool {
1449 self.check_keyword(kw::MacroRules)
dfeec247
XL
1450 && self.look_ahead(1, |t| *t == token::Not)
1451 && self.look_ahead(2, |t| t.is_ident())
74b04a01 1452 }
416331ca 1453
ba9703b0 1454 /// Parses a `macro_rules! foo { ... }` declarative macro.
74b04a01
XL
1455 fn parse_item_macro_rules(&mut self, vis: &Visibility) -> PResult<'a, ItemInfo> {
1456 self.expect_keyword(kw::MacroRules)?; // `macro_rules`
1457 self.expect(&token::Not)?; // `!`
416331ca 1458
74b04a01
XL
1459 let ident = self.parse_ident()?;
1460 let body = self.parse_mac_args()?;
1461 self.eat_semi_for_macro_if_needed(&body);
1462 self.complain_if_pub_macro(vis, true);
e74abb32 1463
ba9703b0 1464 Ok((ident, ItemKind::MacroDef(ast::MacroDef { body, macro_rules: true })))
74b04a01
XL
1465 }
1466
1467 /// Item macro invocations or `macro_rules!` definitions need inherited visibility.
1468 /// If that's not the case, emit an error.
1469 fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
1b1a35ee 1470 if let VisibilityKind::Inherited = vis.kind {
74b04a01 1471 return;
e74abb32
XL
1472 }
1473
74b04a01
XL
1474 let vstr = pprust::vis_to_string(vis);
1475 let vstr = vstr.trim_end();
1476 if macro_rules {
6a06907d 1477 self.sess.gated_spans.gate(sym::pub_macro_rules, vis.span);
74b04a01
XL
1478 } else {
1479 self.struct_span_err(vis.span, "can't qualify macro invocation with `pub`")
1480 .span_suggestion(
1481 vis.span,
1482 "remove the visibility",
1483 String::new(),
1484 Applicability::MachineApplicable,
1485 )
1486 .help(&format!("try adjusting the macro to put `{}` inside the invocation", vstr))
1487 .emit();
1488 }
416331ca
XL
1489 }
1490
74b04a01
XL
1491 fn eat_semi_for_macro_if_needed(&mut self, args: &MacArgs) {
1492 if args.need_semicolon() && !self.eat(&token::Semi) {
1493 self.report_invalid_macro_expansion_item(args);
416331ca
XL
1494 }
1495 }
1496
74b04a01
XL
1497 fn report_invalid_macro_expansion_item(&self, args: &MacArgs) {
1498 let span = args.span().expect("undelimited macro call");
1499 let mut err = self.struct_span_err(
1500 span,
e74abb32 1501 "macros that expand to items must be delimited with braces or followed by a semicolon",
74b04a01
XL
1502 );
1503 if self.unclosed_delims.is_empty() {
1504 let DelimSpan { open, close } = match args {
1505 MacArgs::Empty | MacArgs::Eq(..) => unreachable!(),
1506 MacArgs::Delimited(dspan, ..) => *dspan,
1507 };
1508 err.multipart_suggestion(
1509 "change the delimiters to curly braces",
1510 vec![(open, "{".to_string()), (close, '}'.to_string())],
1511 Applicability::MaybeIncorrect,
1512 );
1513 } else {
1514 err.span_suggestion(
1515 span,
1516 "change the delimiters to curly braces",
1517 " { /* items */ }".to_string(),
1518 Applicability::HasPlaceholders,
1519 );
1520 }
1521 err.span_suggestion(
1522 span.shrink_to_hi(),
e74abb32
XL
1523 "add a semicolon",
1524 ';'.to_string(),
1525 Applicability::MaybeIncorrect,
74b04a01
XL
1526 );
1527 err.emit();
e74abb32
XL
1528 }
1529
60c5eb7d
XL
1530 /// Checks if current token is one of tokens which cannot be nested like `kw::Enum`. In case
1531 /// it is, we try to parse the item and report error about nested types.
1532 fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
dfeec247
XL
1533 if (self.token.is_keyword(kw::Enum)
1534 || self.token.is_keyword(kw::Struct)
1535 || self.token.is_keyword(kw::Union))
1536 && self.look_ahead(1, |t| t.is_ident())
60c5eb7d
XL
1537 {
1538 let kw_token = self.token.clone();
1539 let kw_str = pprust::token_to_string(&kw_token);
5869c6ff 1540 let item = self.parse_item(ForceCollect::No)?;
60c5eb7d
XL
1541
1542 self.struct_span_err(
1543 kw_token.span,
1544 &format!("`{}` definition cannot be nested inside `{}`", kw_str, keyword),
dfeec247
XL
1545 )
1546 .span_suggestion(
60c5eb7d
XL
1547 item.unwrap().span,
1548 &format!("consider creating a new `{}` definition instead of nesting", kw_str),
1549 String::new(),
1550 Applicability::MaybeIncorrect,
dfeec247
XL
1551 )
1552 .emit();
60c5eb7d 1553 // We successfully parsed the item but we must inform the caller about nested problem.
dfeec247 1554 return Ok(false);
60c5eb7d
XL
1555 }
1556 Ok(true)
1557 }
416331ca 1558}
e74abb32
XL
1559
1560/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
74b04a01
XL
1561///
1562/// The function decides if, per-parameter `p`, `p` must have a pattern or just a type.
1563type ReqName = fn(Edition) -> bool;
e74abb32
XL
1564
1565/// Parsing of functions and methods.
1566impl<'a> Parser<'a> {
74b04a01
XL
1567 /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
1568 fn parse_fn(
e74abb32 1569 &mut self,
e74abb32 1570 attrs: &mut Vec<Attribute>,
74b04a01 1571 req_name: ReqName,
3dfed10e 1572 sig_lo: Span,
74b04a01
XL
1573 ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<Block>>)> {
1574 let header = self.parse_fn_front_matter()?; // `const ... fn`
1575 let ident = self.parse_ident()?; // `foo`
1576 let mut generics = self.parse_generics()?; // `<'a, T, ...>`
fc512014 1577 let decl = self.parse_fn_decl(req_name, AllowPlus::Yes, RecoverReturnSign::Yes)?; // `(p: u8, ...)`
74b04a01 1578 generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
3dfed10e
XL
1579
1580 let mut sig_hi = self.prev_token.span;
29967ef6 1581 let body = self.parse_fn_body(attrs, &ident, &mut sig_hi)?; // `;` or `{ ... }`.
3dfed10e
XL
1582 let fn_sig_span = sig_lo.to(sig_hi);
1583 Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, body))
e74abb32
XL
1584 }
1585
74b04a01 1586 /// Parse the "body" of a function.
e74abb32 1587 /// This can either be `;` when there's no body,
74b04a01 1588 /// or e.g. a block when the function is a provided one.
3dfed10e
XL
1589 fn parse_fn_body(
1590 &mut self,
1591 attrs: &mut Vec<Attribute>,
29967ef6 1592 ident: &Ident,
3dfed10e
XL
1593 sig_hi: &mut Span,
1594 ) -> PResult<'a, Option<P<Block>>> {
29967ef6 1595 let (inner_attrs, body) = if self.eat(&token::Semi) {
3dfed10e 1596 // Include the trailing semicolon in the span of the signature
29967ef6 1597 *sig_hi = self.prev_token.span;
ba9703b0
XL
1598 (Vec::new(), None)
1599 } else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() {
1600 self.parse_inner_attrs_and_block().map(|(attrs, body)| (attrs, Some(body)))?
1601 } else if self.token.kind == token::Eq {
1602 // Recover `fn foo() = $expr;`.
1603 self.bump(); // `=`
1604 let eq_sp = self.prev_token.span;
1605 let _ = self.parse_expr()?;
1606 self.expect_semi()?; // `;`
1607 let span = eq_sp.to(self.prev_token.span);
1608 self.struct_span_err(span, "function body cannot be `= expression;`")
1609 .multipart_suggestion(
1610 "surround the expression with `{` and `}` instead of `=` and `;`",
1611 vec![(eq_sp, "{".to_string()), (self.prev_token.span, " }".to_string())],
1612 Applicability::MachineApplicable,
1613 )
1614 .emit();
1615 (Vec::new(), Some(self.mk_block_err(span)))
1616 } else {
29967ef6
XL
1617 if let Err(mut err) =
1618 self.expected_one_of_not_found(&[], &[token::Semi, token::OpenDelim(token::Brace)])
1619 {
1620 if self.token.kind == token::CloseDelim(token::Brace) {
1621 // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in
1622 // the AST for typechecking.
1623 err.span_label(ident.span, "while parsing this `fn`");
1624 err.emit();
1625 (Vec::new(), None)
1626 } else {
1627 return Err(err);
1628 }
1629 } else {
1630 unreachable!()
1631 }
74b04a01
XL
1632 };
1633 attrs.extend(inner_attrs);
1634 Ok(body)
e74abb32
XL
1635 }
1636
74b04a01 1637 /// Is the current token the start of an `FnHeader` / not a valid parse?
6a06907d
XL
1638 ///
1639 /// `check_pub` adds additional `pub` to the checks in case users place it
1640 /// wrongly, can be used to ensure `pub` never comes after `default`.
1641 pub(super) fn check_fn_front_matter(&mut self, check_pub: bool) -> bool {
74b04a01
XL
1642 // We use an over-approximation here.
1643 // `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
6a06907d
XL
1644 // `pub` is added in case users got confused with the ordering like `async pub fn`,
1645 // only if it wasn't preceeded by `default` as `default pub` is invalid.
1646 let quals: &[Symbol] = if check_pub {
1647 &[kw::Pub, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
1648 } else {
1649 &[kw::Const, kw::Async, kw::Unsafe, kw::Extern]
1650 };
74b04a01
XL
1651 self.check_keyword(kw::Fn) // Definitely an `fn`.
1652 // `$qual fn` or `$qual $qual`:
6a06907d 1653 || quals.iter().any(|&kw| self.check_keyword(kw))
74b04a01 1654 && self.look_ahead(1, |t| {
1b1a35ee 1655 // `$qual fn`, e.g. `const fn` or `async fn`.
74b04a01 1656 t.is_keyword(kw::Fn)
1b1a35ee 1657 // Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`.
6a06907d 1658 || t.is_non_raw_ident_where(|i| quals.contains(&i.name)
1b1a35ee
XL
1659 // Rule out 2015 `const async: T = val`.
1660 && i.is_reserved()
1661 // Rule out unsafe extern block.
1662 && !self.is_unsafe_foreign_mod())
74b04a01
XL
1663 })
1664 // `extern ABI fn`
1665 || self.check_keyword(kw::Extern)
1666 && self.look_ahead(1, |t| t.can_begin_literal_maybe_minus())
1667 && self.look_ahead(2, |t| t.is_keyword(kw::Fn))
1668 }
1669
1670 /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration,
1671 /// up to and including the `fn` keyword. The formal grammar is:
e74abb32 1672 ///
74b04a01 1673 /// ```
1b1a35ee 1674 /// Extern = "extern" StringLit? ;
74b04a01 1675 /// FnQual = "const"? "async"? "unsafe"? Extern? ;
1b1a35ee 1676 /// FnFrontMatter = FnQual "fn" ;
74b04a01 1677 /// ```
ba9703b0 1678 pub(super) fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
6a06907d 1679 let sp_start = self.token.span;
74b04a01 1680 let constness = self.parse_constness();
e74abb32 1681 let asyncness = self.parse_asyncness();
e74abb32 1682 let unsafety = self.parse_unsafety();
6a06907d 1683 let ext = self.parse_extern();
74b04a01
XL
1684
1685 if let Async::Yes { span, .. } = asyncness {
1686 self.ban_async_in_2015(span);
1687 }
1688
e74abb32
XL
1689 if !self.eat_keyword(kw::Fn) {
1690 // It is possible for `expect_one_of` to recover given the contents of
1691 // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
1692 // account for this.
6a06907d
XL
1693 match self.expect_one_of(&[], &[]) {
1694 Ok(true) => {}
1695 Ok(false) => unreachable!(),
1696 Err(mut err) => {
1697 // Recover incorrect visibility order such as `async pub`.
1698 if self.check_keyword(kw::Pub) {
1699 let sp = sp_start.to(self.prev_token.span);
1700 if let Ok(snippet) = self.span_to_snippet(sp) {
1701 let vis = self.parse_visibility(FollowedByType::No)?;
1702 let vs = pprust::vis_to_string(&vis);
1703 let vs = vs.trim_end();
1704 err.span_suggestion(
1705 sp_start.to(self.prev_token.span),
1706 &format!("visibility `{}` must come before `{}`", vs, snippet),
1707 format!("{} {}", vs, snippet),
1708 Applicability::MachineApplicable,
1709 );
1710 }
1711 }
1712 return Err(err);
1713 }
dfeec247 1714 }
e74abb32 1715 }
74b04a01 1716
60c5eb7d 1717 Ok(FnHeader { constness, unsafety, asyncness, ext })
e74abb32
XL
1718 }
1719
74b04a01
XL
1720 /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
1721 fn ban_async_in_2015(&self, span: Span) {
1722 if span.rust_2015() {
1723 let diag = self.diagnostic();
5869c6ff
XL
1724 struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015")
1725 .span_label(span, "to use `async fn`, switch to Rust 2018 or later")
1726 .help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION))
74b04a01
XL
1727 .note("for more on editions, read https://doc.rust-lang.org/edition-guide")
1728 .emit();
1729 }
e74abb32
XL
1730 }
1731
1732 /// Parses the parameter list and result type of a function declaration.
1733 pub(super) fn parse_fn_decl(
1734 &mut self,
74b04a01
XL
1735 req_name: ReqName,
1736 ret_allow_plus: AllowPlus,
fc512014 1737 recover_return_sign: RecoverReturnSign,
e74abb32
XL
1738 ) -> PResult<'a, P<FnDecl>> {
1739 Ok(P(FnDecl {
74b04a01 1740 inputs: self.parse_fn_params(req_name)?,
fc512014 1741 output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
e74abb32
XL
1742 }))
1743 }
1744
1745 /// Parses the parameter list of a function, including the `(` and `)` delimiters.
74b04a01
XL
1746 fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, Vec<Param>> {
1747 let mut first_param = true;
1748 // Parse the arguments, starting out with `self` being allowed...
dfeec247 1749 let (mut params, _) = self.parse_paren_comma_seq(|p| {
74b04a01 1750 let param = p.parse_param_general(req_name, first_param).or_else(|mut e| {
dfeec247 1751 e.emit();
74b04a01 1752 let lo = p.prev_token.span;
dfeec247
XL
1753 // Skip every token until next possible arg or end.
1754 p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
1755 // Create a placeholder argument for proper arg count (issue #34264).
5869c6ff 1756 Ok(dummy_arg(Ident::new(kw::Empty, lo.to(p.prev_token.span))))
dfeec247 1757 });
e74abb32 1758 // ...now that we've parsed the first argument, `self` is no longer allowed.
74b04a01 1759 first_param = false;
dfeec247 1760 param
e74abb32 1761 })?;
60c5eb7d 1762 // Replace duplicated recovered params with `_` pattern to avoid unnecessary errors.
e74abb32 1763 self.deduplicate_recovered_params_names(&mut params);
e74abb32
XL
1764 Ok(params)
1765 }
1766
74b04a01
XL
1767 /// Parses a single function parameter.
1768 ///
1769 /// - `self` is syntactically allowed when `first_param` holds.
1770 fn parse_param_general(&mut self, req_name: ReqName, first_param: bool) -> PResult<'a, Param> {
e74abb32
XL
1771 let lo = self.token.span;
1772 let attrs = self.parse_outer_attributes()?;
6a06907d
XL
1773 self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
1774 // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
1775 if let Some(mut param) = this.parse_self_param()? {
1776 param.attrs = attrs.into();
1777 let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) };
1778 return Ok((res?, TrailingToken::None));
1779 }
e74abb32 1780
6a06907d
XL
1781 let is_name_required = match this.token.kind {
1782 token::DotDotDot => false,
1783 _ => req_name(this.token.span.edition()),
1784 };
1785 let (pat, ty) = if is_name_required || this.is_named_param() {
1786 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
1787
1788 let (pat, colon) = this.parse_fn_param_pat_colon()?;
1789 if !colon {
1790 let mut err = this.unexpected::<()>().unwrap_err();
1791 return if let Some(ident) =
1792 this.parameter_without_type(&mut err, pat, is_name_required, first_param)
1793 {
1794 err.emit();
1795 Ok((dummy_arg(ident), TrailingToken::None))
1796 } else {
1797 Err(err)
1798 };
1799 }
e74abb32 1800
6a06907d
XL
1801 this.eat_incorrect_doc_comment_for_param_type();
1802 (pat, this.parse_ty_for_param()?)
1803 } else {
1804 debug!("parse_param_general ident_to_pat");
1805 let parser_snapshot_before_ty = this.clone();
1806 this.eat_incorrect_doc_comment_for_param_type();
1807 let mut ty = this.parse_ty_for_param();
1808 if ty.is_ok()
1809 && this.token != token::Comma
1810 && this.token != token::CloseDelim(token::Paren)
74b04a01 1811 {
6a06907d
XL
1812 // This wasn't actually a type, but a pattern looking like a type,
1813 // so we are going to rollback and re-parse for recovery.
1814 ty = this.unexpected();
e74abb32 1815 }
6a06907d
XL
1816 match ty {
1817 Ok(ty) => {
1818 let ident = Ident::new(kw::Empty, this.prev_token.span);
1819 let bm = BindingMode::ByValue(Mutability::Not);
1820 let pat = this.mk_pat_ident(ty.span, bm, ident);
1821 (pat, ty)
1822 }
1823 // If this is a C-variadic argument and we hit an error, return the error.
1824 Err(err) if this.token == token::DotDotDot => return Err(err),
1825 // Recover from attempting to parse the argument as a type without pattern.
1826 Err(mut err) => {
1827 err.cancel();
1828 *this = parser_snapshot_before_ty;
1829 this.recover_arg_parse()?
1830 }
e74abb32 1831 }
6a06907d 1832 };
e74abb32 1833
6a06907d
XL
1834 let span = lo.until(this.token.span);
1835
1836 Ok((
1837 Param {
1838 attrs: attrs.into(),
1839 id: ast::DUMMY_NODE_ID,
1840 is_placeholder: false,
1841 pat,
1842 span,
1843 ty,
1844 },
1845 TrailingToken::None,
1846 ))
e74abb32
XL
1847 })
1848 }
1849
1850 /// Returns the parsed optional self parameter and whether a self shortcut was used.
e74abb32
XL
1851 fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
1852 // Extract an identifier *after* having confirmed that the token is one.
74b04a01
XL
1853 let expect_self_ident = |this: &mut Self| match this.token.ident() {
1854 Some((ident, false)) => {
1855 this.bump();
1856 ident
e74abb32 1857 }
74b04a01 1858 _ => unreachable!(),
e74abb32
XL
1859 };
1860 // Is `self` `n` tokens ahead?
1861 let is_isolated_self = |this: &Self, n| {
1862 this.is_keyword_ahead(n, &[kw::SelfLower])
dfeec247 1863 && this.look_ahead(n + 1, |t| t != &token::ModSep)
e74abb32
XL
1864 };
1865 // Is `mut self` `n` tokens ahead?
dfeec247
XL
1866 let is_isolated_mut_self =
1867 |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
e74abb32
XL
1868 // Parse `self` or `self: TYPE`. We already know the current token is `self`.
1869 let parse_self_possibly_typed = |this: &mut Self, m| {
1870 let eself_ident = expect_self_ident(this);
74b04a01 1871 let eself_hi = this.prev_token.span;
e74abb32
XL
1872 let eself = if this.eat(&token::Colon) {
1873 SelfKind::Explicit(this.parse_ty()?, m)
1874 } else {
1875 SelfKind::Value(m)
1876 };
1877 Ok((eself, eself_ident, eself_hi))
1878 };
1879 // Recover for the grammar `*self`, `*const self`, and `*mut self`.
1880 let recover_self_ptr = |this: &mut Self| {
1881 let msg = "cannot pass `self` by raw pointer";
1882 let span = this.token.span;
dfeec247 1883 this.struct_span_err(span, msg).span_label(span, msg).emit();
e74abb32 1884
74b04a01 1885 Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
e74abb32
XL
1886 };
1887
1888 // Parse optional `self` parameter of a method.
1889 // Only a limited set of initial token sequences is considered `self` parameters; anything
1890 // else is parsed as a normal function parameter list, so some lookahead is required.
1891 let eself_lo = self.token.span;
74b04a01 1892 let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
e74abb32
XL
1893 token::BinOp(token::And) => {
1894 let eself = if is_isolated_self(self, 1) {
1895 // `&self`
1896 self.bump();
dfeec247 1897 SelfKind::Region(None, Mutability::Not)
e74abb32
XL
1898 } else if is_isolated_mut_self(self, 1) {
1899 // `&mut self`
1900 self.bump();
1901 self.bump();
dfeec247 1902 SelfKind::Region(None, Mutability::Mut)
e74abb32
XL
1903 } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
1904 // `&'lt self`
1905 self.bump();
1906 let lt = self.expect_lifetime();
dfeec247 1907 SelfKind::Region(Some(lt), Mutability::Not)
e74abb32
XL
1908 } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
1909 // `&'lt mut self`
1910 self.bump();
1911 let lt = self.expect_lifetime();
1912 self.bump();
dfeec247 1913 SelfKind::Region(Some(lt), Mutability::Mut)
e74abb32
XL
1914 } else {
1915 // `&not_self`
1916 return Ok(None);
1917 };
74b04a01 1918 (eself, expect_self_ident(self), self.prev_token.span)
e74abb32
XL
1919 }
1920 // `*self`
1921 token::BinOp(token::Star) if is_isolated_self(self, 1) => {
1922 self.bump();
1923 recover_self_ptr(self)?
1924 }
1925 // `*mut self` and `*const self`
dfeec247
XL
1926 token::BinOp(token::Star)
1927 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
e74abb32
XL
1928 {
1929 self.bump();
1930 self.bump();
1931 recover_self_ptr(self)?
1932 }
1933 // `self` and `self: TYPE`
1934 token::Ident(..) if is_isolated_self(self, 0) => {
dfeec247 1935 parse_self_possibly_typed(self, Mutability::Not)?
e74abb32
XL
1936 }
1937 // `mut self` and `mut self: TYPE`
1938 token::Ident(..) if is_isolated_mut_self(self, 0) => {
1939 self.bump();
dfeec247 1940 parse_self_possibly_typed(self, Mutability::Mut)?
e74abb32
XL
1941 }
1942 _ => return Ok(None),
1943 };
1944
1945 let eself = source_map::respan(eself_lo.to(eself_hi), eself);
dfeec247 1946 Ok(Some(Param::from_self(AttrVec::default(), eself, eself_ident)))
e74abb32
XL
1947 }
1948
1949 fn is_named_param(&self) -> bool {
1950 let offset = match self.token.kind {
1951 token::Interpolated(ref nt) => match **nt {
1952 token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
1953 _ => 0,
dfeec247 1954 },
e74abb32
XL
1955 token::BinOp(token::And) | token::AndAnd => 1,
1956 _ if self.token.is_keyword(kw::Mut) => 1,
1957 _ => 0,
1958 };
1959
dfeec247
XL
1960 self.look_ahead(offset, |t| t.is_ident())
1961 && self.look_ahead(offset + 1, |t| t == &token::Colon)
e74abb32
XL
1962 }
1963
1964 fn recover_first_param(&mut self) -> &'static str {
dfeec247
XL
1965 match self
1966 .parse_outer_attributes()
e74abb32
XL
1967 .and_then(|_| self.parse_self_param())
1968 .map_err(|mut e| e.cancel())
1969 {
1970 Ok(Some(_)) => "method",
1971 _ => "function",
1972 }
1973 }
1974}