@@ -3,10 +3,11 @@ use super::{Parser, TokenType};
3
3
use crate::maybe_whole;
4
4
use rustc_ast::ptr::P;
5
5
use rustc_ast::token::{self, Token};
6
- use rustc_ast::{self as ast, AngleBracketedArg, AngleBracketedArgs, ParenthesizedArgs};
7
- use rustc_ast::{AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
8
- use rustc_ast::{GenericArg, GenericArgs};
9
- use rustc_ast::{Path, PathSegment, QSelf};
6
+ use rustc_ast::{
7
+ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocTyConstraint,
8
+ AssocTyConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
9
+ Path, PathSegment, QSelf,
10
+ };
10
11
use rustc_errors::{pluralize, Applicability, PResult};
11
12
use rustc_span::source_map::{BytePos, Span};
12
13
use rustc_span::symbol::{kw, sym, Ident};
@@ -78,7 +79,7 @@ impl<'a> Parser<'a> {
78
79
}
79
80
80
81
let qself = QSelf { ty, path_span, position: path.segments.len() };
81
- self.parse_path_segments(&mut path.segments, style)?;
82
+ self.parse_path_segments(&mut path.segments, style, None )?;
82
83
83
84
Ok((
84
85
qself,
@@ -119,6 +120,10 @@ impl<'a> Parser<'a> {
119
120
true
120
121
}
121
122
123
+ pub(super) fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> {
124
+ self.parse_path_inner(style, None)
125
+ }
126
+
122
127
/// Parses simple paths.
123
128
///
124
129
/// `path = [::] segment+`
@@ -129,7 +134,11 @@ impl<'a> Parser<'a> {
129
134
/// `a::b::C::<D>` (with disambiguator)
130
135
/// `Fn(Args)` (without disambiguator)
131
136
/// `Fn::(Args)` (with disambiguator)
132
- pub(super) fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> {
137
+ pub(super) fn parse_path_inner(
138
+ &mut self,
139
+ style: PathStyle,
140
+ ty_generics: Option<&Generics>,
141
+ ) -> PResult<'a, Path> {
133
142
maybe_whole!(self, NtPath, |path| {
134
143
if style == PathStyle::Mod && path.segments.iter().any(|segment| segment.args.is_some())
135
144
{
@@ -152,7 +161,7 @@ impl<'a> Parser<'a> {
152
161
if self.eat(&token::ModSep) {
153
162
segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
154
163
}
155
- self.parse_path_segments(&mut segments, style)?;
164
+ self.parse_path_segments(&mut segments, style, ty_generics )?;
156
165
157
166
Ok(Path { segments, span: lo.to(self.prev_token.span), tokens: None })
158
167
}
@@ -161,9 +170,10 @@ impl<'a> Parser<'a> {
161
170
&mut self,
162
171
segments: &mut Vec<PathSegment>,
163
172
style: PathStyle,
173
+ ty_generics: Option<&Generics>,
164
174
) -> PResult<'a, ()> {
165
175
loop {
166
- let segment = self.parse_path_segment(style)?;
176
+ let segment = self.parse_path_segment(style, ty_generics )?;
167
177
if style == PathStyle::Expr {
168
178
// In order to check for trailing angle brackets, we must have finished
169
179
// recursing (`parse_path_segment` can indirectly call this function),
@@ -191,7 +201,11 @@ impl<'a> Parser<'a> {
191
201
}
192
202
}
193
203
194
- pub(super) fn parse_path_segment(&mut self, style: PathStyle) -> PResult<'a, PathSegment> {
204
+ pub(super) fn parse_path_segment(
205
+ &mut self,
206
+ style: PathStyle,
207
+ ty_generics: Option<&Generics>,
208
+ ) -> PResult<'a, PathSegment> {
195
209
let ident = self.parse_path_segment_ident()?;
196
210
let is_args_start = |token: &Token| {
197
211
matches!(
@@ -229,18 +243,21 @@ impl<'a> Parser<'a> {
229
243
let lo = self.token.span;
230
244
let args = if self.eat_lt() {
231
245
// `<'a, T, A = U>`
232
- let args =
233
- self.parse_angle_args_with_leading_angle_bracket_recovery(style, lo)?;
246
+ let args = self.parse_angle_args_with_leading_angle_bracket_recovery(
247
+ style,
248
+ lo,
249
+ ty_generics,
250
+ )?;
234
251
self.expect_gt()?;
235
252
let span = lo.to(self.prev_token.span);
236
253
AngleBracketedArgs { args, span }.into()
237
254
} else {
238
255
// `(T, U) -> R`
239
256
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
240
257
let inputs_span = lo.to(self.prev_token.span);
241
- let span = ident.span.to(self.prev_token.span);
242
258
let output =
243
259
self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
260
+ let span = ident.span.to(self.prev_token.span);
244
261
ParenthesizedArgs { span, inputs, inputs_span, output }.into()
245
262
};
246
263
@@ -275,6 +292,7 @@ impl<'a> Parser<'a> {
275
292
&mut self,
276
293
style: PathStyle,
277
294
lo: Span,
295
+ ty_generics: Option<&Generics>,
278
296
) -> PResult<'a, Vec<AngleBracketedArg>> {
279
297
// We need to detect whether there are extra leading left angle brackets and produce an
280
298
// appropriate error and suggestion. This cannot be implemented by looking ahead at
@@ -350,7 +368,7 @@ impl<'a> Parser<'a> {
350
368
let snapshot = if is_first_invocation { Some(self.clone()) } else { None };
351
369
352
370
debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)");
353
- match self.parse_angle_args() {
371
+ match self.parse_angle_args(ty_generics ) {
354
372
Ok(args) => Ok(args),
355
373
Err(mut e) if is_first_invocation && self.unmatched_angle_bracket_count > 0 => {
356
374
// Swap `self` with our backup of the parser state before attempting to parse
@@ -403,7 +421,7 @@ impl<'a> Parser<'a> {
403
421
.emit();
404
422
405
423
// Try again without unmatched angle bracket characters.
406
- self.parse_angle_args()
424
+ self.parse_angle_args(ty_generics )
407
425
}
408
426
}
409
427
Err(e) => Err(e),
@@ -412,9 +430,12 @@ impl<'a> Parser<'a> {
412
430
413
431
/// Parses (possibly empty) list of generic arguments / associated item constraints,
414
432
/// possibly including trailing comma.
415
- pub(super) fn parse_angle_args(&mut self) -> PResult<'a, Vec<AngleBracketedArg>> {
433
+ pub(super) fn parse_angle_args(
434
+ &mut self,
435
+ ty_generics: Option<&Generics>,
436
+ ) -> PResult<'a, Vec<AngleBracketedArg>> {
416
437
let mut args = Vec::new();
417
- while let Some(arg) = self.parse_angle_arg()? {
438
+ while let Some(arg) = self.parse_angle_arg(ty_generics )? {
418
439
args.push(arg);
419
440
if !self.eat(&token::Comma) {
420
441
if !self.token.kind.should_end_const_arg() {
@@ -431,9 +452,12 @@ impl<'a> Parser<'a> {
431
452
}
432
453
433
454
/// Parses a single argument in the angle arguments `<...>` of a path segment.
434
- fn parse_angle_arg(&mut self) -> PResult<'a, Option<AngleBracketedArg>> {
455
+ fn parse_angle_arg(
456
+ &mut self,
457
+ ty_generics: Option<&Generics>,
458
+ ) -> PResult<'a, Option<AngleBracketedArg>> {
435
459
let lo = self.token.span;
436
- let arg = self.parse_generic_arg()?;
460
+ let arg = self.parse_generic_arg(ty_generics )?;
437
461
match arg {
438
462
Some(arg) => {
439
463
if self.check(&token::Colon) | self.check(&token::Eq) {
@@ -476,7 +500,7 @@ impl<'a> Parser<'a> {
476
500
/// That is, parse `<term>` in `Item = <term>`.
477
501
/// Right now, this only admits types in `<term>`.
478
502
fn parse_assoc_equality_term(&mut self, ident: Ident, eq: Span) -> PResult<'a, P<ast::Ty>> {
479
- let arg = self.parse_generic_arg()?;
503
+ let arg = self.parse_generic_arg(None )?;
480
504
let span = ident.span.to(self.prev_token.span);
481
505
match arg {
482
506
Some(GenericArg::Type(ty)) => return Ok(ty),
@@ -563,7 +587,10 @@ impl<'a> Parser<'a> {
563
587
564
588
/// Parse a generic argument in a path segment.
565
589
/// This does not include constraints, e.g., `Item = u8`, which is handled in `parse_angle_arg`.
566
- pub(super) fn parse_generic_arg(&mut self) -> PResult<'a, Option<GenericArg>> {
590
+ pub(super) fn parse_generic_arg(
591
+ &mut self,
592
+ ty_generics: Option<&Generics>,
593
+ ) -> PResult<'a, Option<GenericArg>> {
567
594
let start = self.token.span;
568
595
let arg = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
569
596
// Parse lifetime argument.
@@ -580,25 +607,8 @@ impl<'a> Parser<'a> {
580
607
return self.recover_const_arg(start, err).map(Some);
581
608
}
582
609
}
583
- } else if self.eat_keyword_noexpect(kw::Const) {
584
- // Detect and recover from the old, pre-RFC2000 syntax for const generics.
585
- let mut err = self.struct_span_err(
586
- start,
587
- "expected lifetime, type, or constant, found keyword `const`",
588
- );
589
- if self.check_const_arg() {
590
- err.span_suggestion_verbose(
591
- start.until(self.token.span),
592
- "the `const` keyword is only needed in the definition of the type",
593
- String::new(),
594
- Applicability::MaybeIncorrect,
595
- );
596
- err.emit();
597
- GenericArg::Const(self.parse_const_arg()?)
598
- } else {
599
- let after_kw_const = self.token.span;
600
- return self.recover_const_arg(after_kw_const, err).map(Some);
601
- }
610
+ } else if self.token.is_keyword(kw::Const) {
611
+ return self.recover_const_param_declaration(ty_generics);
602
612
} else {
603
613
return Ok(None);
604
614
};
0 commit comments