]> git.lizzy.rs Git - rust.git/blob - src/librustc_parse/parser/ty.rs
Rollup merge of #67875 - dtolnay:hidden, r=GuillaumeGomez
[rust.git] / src / librustc_parse / parser / ty.rs
1 use super::item::ParamCfg;
2 use super::{Parser, PathStyle, PrevTokenKind, TokenType};
3
4 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
5
6 use rustc_error_codes::*;
7 use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
8 use rustc_span::source_map::Span;
9 use rustc_span::symbol::kw;
10 use syntax::ast::{
11     self, BareFnTy, FunctionRetTy, GenericParam, Ident, Lifetime, MutTy, Ty, TyKind,
12 };
13 use syntax::ast::{
14     GenericBound, GenericBounds, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax,
15 };
16 use syntax::ast::{Mac, Mutability};
17 use syntax::ptr::P;
18 use syntax::token::{self, Token};
19
20 /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
21 /// `IDENT<<u8 as Trait>::AssocTy>`.
22 ///
23 /// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes
24 /// that `IDENT` is not the ident of a fn trait.
25 fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
26     t == &token::ModSep || t == &token::Lt || t == &token::BinOp(token::Shl)
27 }
28
29 impl<'a> Parser<'a> {
30     /// Parses a type.
31     pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
32         self.parse_ty_common(true, true, false)
33     }
34
35     /// Parse a type suitable for a function or function pointer parameter.
36     /// The difference from `parse_ty` is that this version allows `...`
37     /// (`CVarArgs`) at the top level of the the type.
38     pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
39         self.parse_ty_common(true, true, true)
40     }
41
42     /// Parses a type in restricted contexts where `+` is not permitted.
43     ///
44     /// Example 1: `&'a TYPE`
45     ///     `+` is prohibited to maintain operator priority (P(+) < P(&)).
46     /// Example 2: `value1 as TYPE + value2`
47     ///     `+` is prohibited to avoid interactions with expression grammar.
48     pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
49         self.parse_ty_common(false, true, false)
50     }
51
52     /// Parses an optional return type `[ -> TY ]` in a function declaration.
53     pub(super) fn parse_ret_ty(
54         &mut self,
55         allow_plus: bool,
56         allow_qpath_recovery: bool,
57     ) -> PResult<'a, FunctionRetTy> {
58         Ok(if self.eat(&token::RArrow) {
59             // FIXME(Centril): Can we unconditionally `allow_plus`?
60             FunctionRetTy::Ty(self.parse_ty_common(allow_plus, allow_qpath_recovery, false)?)
61         } else {
62             FunctionRetTy::Default(self.token.span.shrink_to_lo())
63         })
64     }
65
66     fn parse_ty_common(
67         &mut self,
68         allow_plus: bool,
69         allow_qpath_recovery: bool,
70         // Is `...` (`CVarArgs`) legal in the immediate top level call?
71         allow_c_variadic: bool,
72     ) -> PResult<'a, P<Ty>> {
73         maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
74         maybe_whole!(self, NtTy, |x| x);
75
76         let lo = self.token.span;
77         let mut impl_dyn_multi = false;
78         let kind = if self.check(&token::OpenDelim(token::Paren)) {
79             self.parse_ty_tuple_or_parens(lo, allow_plus)?
80         } else if self.eat(&token::Not) {
81             // Never type `!`
82             TyKind::Never
83         } else if self.eat(&token::BinOp(token::Star)) {
84             self.parse_ty_ptr()?
85         } else if self.eat(&token::OpenDelim(token::Bracket)) {
86             self.parse_array_or_slice_ty()?
87         } else if self.check(&token::BinOp(token::And)) || self.check(&token::AndAnd) {
88             // Reference
89             self.expect_and()?;
90             self.parse_borrowed_pointee()?
91         } else if self.eat_keyword_noexpect(kw::Typeof) {
92             self.parse_typeof_ty()?
93         } else if self.eat_keyword(kw::Underscore) {
94             // A type to be inferred `_`
95             TyKind::Infer
96         } else if self.token_is_bare_fn_keyword() {
97             // Function pointer type
98             self.parse_ty_bare_fn(Vec::new())?
99         } else if self.check_keyword(kw::For) {
100             // Function pointer type or bound list (trait object type) starting with a poly-trait.
101             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
102             //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
103             let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
104             if self.token_is_bare_fn_keyword() {
105                 self.parse_ty_bare_fn(lifetime_defs)?
106             } else {
107                 let path = self.parse_path(PathStyle::Type)?;
108                 let parse_plus = allow_plus && self.check_plus();
109                 self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)?
110             }
111         } else if self.eat_keyword(kw::Impl) {
112             self.parse_impl_ty(&mut impl_dyn_multi)?
113         } else if self.is_explicit_dyn_type() {
114             self.parse_dyn_ty(&mut impl_dyn_multi)?
115         } else if self.check(&token::Question)
116             || self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus())
117         {
118             // Bound list (trait object type)
119             let bounds = self.parse_generic_bounds_common(allow_plus, None)?;
120             TyKind::TraitObject(bounds, TraitObjectSyntax::None)
121         } else if self.eat_lt() {
122             // Qualified path
123             let (qself, path) = self.parse_qpath(PathStyle::Type)?;
124             TyKind::Path(Some(qself), path)
125         } else if self.token.is_path_start() {
126             self.parse_path_start_ty(lo, allow_plus)?
127         } else if self.eat(&token::DotDotDot) {
128             if allow_c_variadic {
129                 TyKind::CVarArgs
130             } else {
131                 // FIXME(Centril): Should we just allow `...` syntactically
132                 // anywhere in a type and use semantic restrictions instead?
133                 self.error_illegal_c_varadic_ty(lo);
134                 TyKind::Err
135             }
136         } else {
137             let msg = format!("expected type, found {}", super::token_descr(&self.token));
138             let mut err = self.struct_span_err(self.token.span, &msg);
139             err.span_label(self.token.span, "expected type");
140             self.maybe_annotate_with_ascription(&mut err, true);
141             return Err(err);
142         };
143
144         let span = lo.to(self.prev_span);
145         let ty = self.mk_ty(span, kind);
146
147         // Try to recover from use of `+` with incorrect priority.
148         self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty);
149         self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
150         self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)
151     }
152
153     /// Parses either:
154     /// - `(TYPE)`, a parenthesized type.
155     /// - `(TYPE,)`, a tuple with a single field of type TYPE.
156     fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: bool) -> PResult<'a, TyKind> {
157         let mut trailing_plus = false;
158         let (ts, trailing) = self.parse_paren_comma_seq(|p| {
159             let ty = p.parse_ty()?;
160             trailing_plus = p.prev_token_kind == PrevTokenKind::Plus;
161             Ok(ty)
162         })?;
163
164         if ts.len() == 1 && !trailing {
165             let ty = ts.into_iter().nth(0).unwrap().into_inner();
166             let maybe_bounds = allow_plus && self.token.is_like_plus();
167             match ty.kind {
168                 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
169                 TyKind::Path(None, path) if maybe_bounds => {
170                     self.parse_remaining_bounds(Vec::new(), path, lo, true)
171                 }
172                 TyKind::TraitObject(mut bounds, TraitObjectSyntax::None)
173                     if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
174                 {
175                     let path = match bounds.remove(0) {
176                         GenericBound::Trait(pt, ..) => pt.trait_ref.path,
177                         GenericBound::Outlives(..) => {
178                             self.span_bug(ty.span, "unexpected lifetime bound")
179                         }
180                     };
181                     self.parse_remaining_bounds(Vec::new(), path, lo, true)
182                 }
183                 // `(TYPE)`
184                 _ => Ok(TyKind::Paren(P(ty))),
185             }
186         } else {
187             Ok(TyKind::Tup(ts))
188         }
189     }
190
191     fn parse_remaining_bounds(
192         &mut self,
193         generic_params: Vec<GenericParam>,
194         path: ast::Path,
195         lo: Span,
196         parse_plus: bool,
197     ) -> PResult<'a, TyKind> {
198         let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
199         let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
200         if parse_plus {
201             self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
202             bounds.append(&mut self.parse_generic_bounds(Some(self.prev_span))?);
203         }
204         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
205     }
206
207     /// Parses a raw pointer type: `*[const | mut] $type`.
208     fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
209         let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
210             let span = self.prev_span;
211             let msg = "expected mut or const in raw pointer type";
212             self.struct_span_err(span, msg)
213                 .span_label(span, msg)
214                 .help("use `*mut T` or `*const T` as appropriate")
215                 .emit();
216             Mutability::Not
217         });
218         let ty = self.parse_ty_no_plus()?;
219         Ok(TyKind::Ptr(MutTy { ty, mutbl }))
220     }
221
222     /// Parses an array (`[TYPE; EXPR]`) or slice (`[TYPE]`) type.
223     /// The opening `[` bracket is already eaten.
224     fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
225         let elt_ty = self.parse_ty()?;
226         let ty = if self.eat(&token::Semi) {
227             TyKind::Array(elt_ty, self.parse_anon_const_expr()?)
228         } else {
229             TyKind::Slice(elt_ty)
230         };
231         self.expect(&token::CloseDelim(token::Bracket))?;
232         Ok(ty)
233     }
234
235     fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
236         let opt_lifetime = if self.check_lifetime() { Some(self.expect_lifetime()) } else { None };
237         let mutbl = self.parse_mutability();
238         let ty = self.parse_ty_no_plus()?;
239         Ok(TyKind::Rptr(opt_lifetime, MutTy { ty, mutbl }))
240     }
241
242     // Parses the `typeof(EXPR)`.
243     // To avoid ambiguity, the type is surrounded by parenthesis.
244     fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> {
245         self.expect(&token::OpenDelim(token::Paren))?;
246         let expr = self.parse_anon_const_expr()?;
247         self.expect(&token::CloseDelim(token::Paren))?;
248         Ok(TyKind::Typeof(expr))
249     }
250
251     /// Is the current token one of the keywords that signals a bare function type?
252     fn token_is_bare_fn_keyword(&mut self) -> bool {
253         self.check_keyword(kw::Fn)
254             || self.check_keyword(kw::Unsafe)
255             || self.check_keyword(kw::Extern)
256     }
257
258     /// Parses a function pointer type (`TyKind::BareFn`).
259     /// ```
260     /// [unsafe] [extern "ABI"] fn (S) -> T
261     ///  ^~~~~^          ^~~~^     ^~^    ^
262     ///    |               |        |     |
263     ///    |               |        |   Return type
264     /// Function Style    ABI  Parameter types
265     /// ```
266     fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a, TyKind> {
267         let unsafety = self.parse_unsafety();
268         let ext = self.parse_extern()?;
269         self.expect_keyword(kw::Fn)?;
270         let cfg = ParamCfg { is_self_allowed: false, is_name_required: |_| false };
271         let decl = self.parse_fn_decl(cfg, false)?;
272         Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl })))
273     }
274
275     /// Parses an `impl B0 + ... + Bn` type.
276     fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
277         // Always parse bounds greedily for better error recovery.
278         let bounds = self.parse_generic_bounds(None)?;
279         *impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
280         Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
281     }
282
283     /// Is a `dyn B0 + ... + Bn` type allowed here?
284     fn is_explicit_dyn_type(&mut self) -> bool {
285         self.check_keyword(kw::Dyn)
286             && (self.token.span.rust_2018()
287                 || self.look_ahead(1, |t| {
288                     t.can_begin_bound() && !can_continue_type_after_non_fn_ident(t)
289                 }))
290     }
291
292     /// Parses a `dyn B0 + ... + Bn` type.
293     ///
294     /// Note that this does *not* parse bare trait objects.
295     fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
296         self.bump(); // `dyn`
297         // Always parse bounds greedily for better error recovery.
298         let bounds = self.parse_generic_bounds(None)?;
299         *impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
300         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn))
301     }
302
303     /// Parses a type starting with a path.
304     ///
305     /// This can be:
306     /// 1. a type macro, `mac!(...)`,
307     /// 2. a bare trait object, `B0 + ... + Bn`,
308     /// 3. or a path, `path::to::MyType`.
309     fn parse_path_start_ty(&mut self, lo: Span, allow_plus: bool) -> PResult<'a, TyKind> {
310         // Simple path
311         let path = self.parse_path(PathStyle::Type)?;
312         if self.eat(&token::Not) {
313             // Macro invocation in type position
314             Ok(TyKind::Mac(Mac {
315                 path,
316                 args: self.parse_mac_args()?,
317                 prior_type_ascription: self.last_type_ascription,
318             }))
319         } else if allow_plus && self.check_plus() {
320             // `Trait1 + Trait2 + 'a`
321             self.parse_remaining_bounds(Vec::new(), path, lo, true)
322         } else {
323             // Just a type path.
324             Ok(TyKind::Path(None, path))
325         }
326     }
327
328     fn error_illegal_c_varadic_ty(&self, lo: Span) {
329         struct_span_err!(
330             self.sess.span_diagnostic,
331             lo.to(self.prev_span),
332             E0743,
333             "C-variadic type `...` may not be nested inside another type",
334         )
335         .emit();
336     }
337
338     pub(super) fn parse_generic_bounds(
339         &mut self,
340         colon_span: Option<Span>,
341     ) -> PResult<'a, GenericBounds> {
342         self.parse_generic_bounds_common(true, colon_span)
343     }
344
345     /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
346     ///
347     /// See `parse_generic_bound` for the `BOUND` grammar.
348     fn parse_generic_bounds_common(
349         &mut self,
350         allow_plus: bool,
351         colon_span: Option<Span>,
352     ) -> PResult<'a, GenericBounds> {
353         let mut bounds = Vec::new();
354         let mut negative_bounds = Vec::new();
355         while self.can_begin_bound() {
356             match self.parse_generic_bound()? {
357                 Ok(bound) => bounds.push(bound),
358                 Err(neg_sp) => negative_bounds.push(neg_sp),
359             }
360             if !allow_plus || !self.eat_plus() {
361                 break;
362             }
363         }
364
365         if !negative_bounds.is_empty() {
366             self.error_negative_bounds(colon_span, &bounds, negative_bounds);
367         }
368
369         Ok(bounds)
370     }
371
372     /// Can the current token begin a bound?
373     fn can_begin_bound(&mut self) -> bool {
374         // This needs to be synchronized with `TokenKind::can_begin_bound`.
375         self.check_path()
376         || self.check_lifetime()
377         || self.check(&token::Not) // Used for error reporting only.
378         || self.check(&token::Question)
379         || self.check_keyword(kw::For)
380         || self.check(&token::OpenDelim(token::Paren))
381     }
382
383     fn error_negative_bounds(
384         &self,
385         colon_span: Option<Span>,
386         bounds: &[GenericBound],
387         negative_bounds: Vec<Span>,
388     ) {
389         let negative_bounds_len = negative_bounds.len();
390         let last_span = *negative_bounds.last().expect("no negative bounds, but still error?");
391         let mut err = self.struct_span_err(negative_bounds, "negative bounds are not supported");
392         err.span_label(last_span, "negative bounds are not supported");
393         if let Some(bound_list) = colon_span {
394             let bound_list = bound_list.to(self.prev_span);
395             let mut new_bound_list = String::new();
396             if !bounds.is_empty() {
397                 let mut snippets = bounds.iter().map(|bound| self.span_to_snippet(bound.span()));
398                 while let Some(Ok(snippet)) = snippets.next() {
399                     new_bound_list.push_str(" + ");
400                     new_bound_list.push_str(&snippet);
401                 }
402                 new_bound_list = new_bound_list.replacen(" +", ":", 1);
403             }
404             err.tool_only_span_suggestion(
405                 bound_list,
406                 &format!("remove the bound{}", pluralize!(negative_bounds_len)),
407                 new_bound_list,
408                 Applicability::MachineApplicable,
409             );
410         }
411         err.emit();
412     }
413
414     /// Parses a bound according to the grammar:
415     /// ```
416     /// BOUND = TY_BOUND | LT_BOUND
417     /// ```
418     fn parse_generic_bound(&mut self) -> PResult<'a, Result<GenericBound, Span>> {
419         let anchor_lo = self.prev_span;
420         let lo = self.token.span;
421         let has_parens = self.eat(&token::OpenDelim(token::Paren));
422         let inner_lo = self.token.span;
423         let is_negative = self.eat(&token::Not);
424         let question = self.eat(&token::Question).then_some(self.prev_span);
425         let bound = if self.token.is_lifetime() {
426             self.parse_generic_lt_bound(lo, inner_lo, has_parens, question)?
427         } else {
428             self.parse_generic_ty_bound(lo, has_parens, question)?
429         };
430         Ok(if is_negative { Err(anchor_lo.to(self.prev_span)) } else { Ok(bound) })
431     }
432
433     /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
434     /// ```
435     /// LT_BOUND = LIFETIME
436     /// ```
437     fn parse_generic_lt_bound(
438         &mut self,
439         lo: Span,
440         inner_lo: Span,
441         has_parens: bool,
442         question: Option<Span>,
443     ) -> PResult<'a, GenericBound> {
444         self.error_opt_out_lifetime(question);
445         let bound = GenericBound::Outlives(self.expect_lifetime());
446         if has_parens {
447             // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
448             // possibly introducing `GenericBound::Paren(P<GenericBound>)`?
449             self.recover_paren_lifetime(lo, inner_lo)?;
450         }
451         Ok(bound)
452     }
453
454     fn error_opt_out_lifetime(&self, question: Option<Span>) {
455         if let Some(span) = question {
456             self.struct_span_err(span, "`?` may only modify trait bounds, not lifetime bounds")
457                 .emit();
458         }
459     }
460
461     /// Recover on `('lifetime)` with `(` already eaten.
462     fn recover_paren_lifetime(&mut self, lo: Span, inner_lo: Span) -> PResult<'a, ()> {
463         let inner_span = inner_lo.to(self.prev_span);
464         self.expect(&token::CloseDelim(token::Paren))?;
465         let mut err = self.struct_span_err(
466             lo.to(self.prev_span),
467             "parenthesized lifetime bounds are not supported",
468         );
469         if let Ok(snippet) = self.span_to_snippet(inner_span) {
470             err.span_suggestion_short(
471                 lo.to(self.prev_span),
472                 "remove the parentheses",
473                 snippet.to_owned(),
474                 Applicability::MachineApplicable,
475             );
476         }
477         err.emit();
478         Ok(())
479     }
480
481     /// Parses a type bound according to:
482     /// ```
483     /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
484     /// TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
485     /// ```
486     fn parse_generic_ty_bound(
487         &mut self,
488         lo: Span,
489         has_parens: bool,
490         question: Option<Span>,
491     ) -> PResult<'a, GenericBound> {
492         let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
493         let path = self.parse_path(PathStyle::Type)?;
494         if has_parens {
495             self.expect(&token::CloseDelim(token::Paren))?;
496         }
497         let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
498         let modifier = question.map_or(TraitBoundModifier::None, |_| TraitBoundModifier::Maybe);
499         Ok(GenericBound::Trait(poly_trait, modifier))
500     }
501
502     /// Optionally parses `for<$generic_params>`.
503     pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
504         if self.eat_keyword(kw::For) {
505             self.expect_lt()?;
506             let params = self.parse_generic_params()?;
507             self.expect_gt()?;
508             // We rely on AST validation to rule out invalid cases: There must not be type
509             // parameters, and the lifetime parameters must not have bounds.
510             Ok(params)
511         } else {
512             Ok(Vec::new())
513         }
514     }
515
516     pub fn check_lifetime(&mut self) -> bool {
517         self.expected_tokens.push(TokenType::Lifetime);
518         self.token.is_lifetime()
519     }
520
521     /// Parses a single lifetime `'a` or panics.
522     pub fn expect_lifetime(&mut self) -> Lifetime {
523         if let Some(ident) = self.token.lifetime() {
524             let span = self.token.span;
525             self.bump();
526             Lifetime { ident: Ident::new(ident.name, span), id: ast::DUMMY_NODE_ID }
527         } else {
528             self.span_bug(self.token.span, "not a lifetime")
529         }
530     }
531
532     pub(super) fn mk_ty(&self, span: Span, kind: TyKind) -> P<Ty> {
533         P(Ty { kind, span, id: ast::DUMMY_NODE_ID })
534     }
535 }