@@ -352,12 +352,7 @@ impl<'a> Parser<'a> {
352
352
353
353
/// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
354
354
///
355
- /// ```
356
- /// BOUND = TY_BOUND | LT_BOUND
357
- /// LT_BOUND = LIFETIME (e.g., `'a`)
358
- /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
359
- /// TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
360
- /// ```
355
+ /// See `parse_generic_bound` for the `BOUND` grammar.
361
356
fn parse_generic_bounds_common (
362
357
& mut self ,
363
358
allow_plus : bool ,
@@ -368,39 +363,13 @@ impl<'a> Parser<'a> {
368
363
let mut last_plus_span = None ;
369
364
let mut was_negative = false ;
370
365
while self . can_begin_bound ( ) {
371
- let lo = self . token . span ;
372
- let has_parens = self . eat ( & token:: OpenDelim ( token:: Paren ) ) ;
373
- let inner_lo = self . token . span ;
374
- let is_negative = self . eat ( & token:: Not ) ;
375
- let question = if self . eat ( & token:: Question ) { Some ( self . prev_span ) } else { None } ;
376
- if self . token . is_lifetime ( ) {
377
- self . error_opt_out_lifetime ( question) ;
378
- bounds. push ( GenericBound :: Outlives ( self . expect_lifetime ( ) ) ) ;
379
- if has_parens {
380
- self . recover_paren_lifetime ( lo, inner_lo) ?;
381
- }
382
- } else {
383
- let lifetime_defs = self . parse_late_bound_lifetime_defs ( ) ?;
384
- let path = self . parse_path ( PathStyle :: Type ) ?;
385
- if has_parens {
386
- self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?;
387
- }
388
- let poly_span = lo. to ( self . prev_span ) ;
389
- if is_negative {
390
- was_negative = true ;
391
- if let Some ( sp) = last_plus_span. or ( colon_span) {
392
- negative_bounds. push ( sp. to ( poly_span) ) ;
393
- }
394
- } else {
395
- let poly_trait = PolyTraitRef :: new ( lifetime_defs, path, poly_span) ;
396
- let modifier = if question. is_some ( ) {
397
- TraitBoundModifier :: Maybe
398
- } else {
399
- TraitBoundModifier :: None
400
- } ;
401
- bounds. push ( GenericBound :: Trait ( poly_trait, modifier) ) ;
402
- }
403
- }
366
+ self . parse_generic_bound (
367
+ colon_span,
368
+ last_plus_span,
369
+ & mut bounds,
370
+ & mut negative_bounds,
371
+ & mut was_negative,
372
+ ) ?;
404
373
405
374
if !allow_plus || !self . eat_plus ( ) {
406
375
break
@@ -441,7 +410,7 @@ impl<'a> Parser<'a> {
441
410
err. emit ( ) ;
442
411
}
443
412
444
- return Ok ( bounds) ;
413
+ Ok ( bounds)
445
414
}
446
415
447
416
/// Can the current token begin a bound?
@@ -455,6 +424,58 @@ impl<'a> Parser<'a> {
455
424
|| self . check ( & token:: OpenDelim ( token:: Paren ) )
456
425
}
457
426
427
+ /// Parses a bound according to the grammar:
428
+ ///
429
+ /// ```
430
+ /// BOUND = TY_BOUND | LT_BOUND
431
+ /// LT_BOUND = LIFETIME (e.g., `'a`)
432
+ /// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
433
+ /// TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
434
+ /// ```
435
+ fn parse_generic_bound (
436
+ & mut self ,
437
+ colon_span : Option < Span > ,
438
+ last_plus_span : Option < Span > ,
439
+ bounds : & mut Vec < GenericBound > ,
440
+ negative_bounds : & mut Vec < Span > ,
441
+ was_negative : & mut bool ,
442
+ ) -> PResult < ' a , ( ) > {
443
+ let lo = self . token . span ;
444
+ let has_parens = self . eat ( & token:: OpenDelim ( token:: Paren ) ) ;
445
+ let inner_lo = self . token . span ;
446
+ let is_negative = self . eat ( & token:: Not ) ;
447
+ let question = if self . eat ( & token:: Question ) { Some ( self . prev_span ) } else { None } ;
448
+ if self . token . is_lifetime ( ) {
449
+ self . error_opt_out_lifetime ( question) ;
450
+ bounds. push ( GenericBound :: Outlives ( self . expect_lifetime ( ) ) ) ;
451
+ if has_parens {
452
+ self . recover_paren_lifetime ( lo, inner_lo) ?;
453
+ }
454
+ } else {
455
+ let lifetime_defs = self . parse_late_bound_lifetime_defs ( ) ?;
456
+ let path = self . parse_path ( PathStyle :: Type ) ?;
457
+ if has_parens {
458
+ self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?;
459
+ }
460
+ let poly_span = lo. to ( self . prev_span ) ;
461
+ if is_negative {
462
+ * was_negative = true ;
463
+ if let Some ( sp) = last_plus_span. or ( colon_span) {
464
+ negative_bounds. push ( sp. to ( poly_span) ) ;
465
+ }
466
+ } else {
467
+ let poly_trait = PolyTraitRef :: new ( lifetime_defs, path, poly_span) ;
468
+ let modifier = if question. is_some ( ) {
469
+ TraitBoundModifier :: Maybe
470
+ } else {
471
+ TraitBoundModifier :: None
472
+ } ;
473
+ bounds. push ( GenericBound :: Trait ( poly_trait, modifier) ) ;
474
+ }
475
+ }
476
+ Ok ( ( ) )
477
+ }
478
+
458
479
fn error_opt_out_lifetime ( & self , question : Option < Span > ) {
459
480
if let Some ( span) = question {
460
481
self . struct_span_err ( span, "`?` may only modify trait bounds, not lifetime bounds" )
0 commit comments