@@ -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