@@ -352,12 +352,7 @@ impl<'a> Parser<'a> {
352352
353353 /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`.
354354 ///
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.
361356 fn parse_generic_bounds_common (
362357 & mut self ,
363358 allow_plus : bool ,
@@ -368,39 +363,13 @@ impl<'a> Parser<'a> {
368363 let mut last_plus_span = None ;
369364 let mut was_negative = false ;
370365 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+ ) ?;
404373
405374 if !allow_plus || !self . eat_plus ( ) {
406375 break
@@ -441,7 +410,7 @@ impl<'a> Parser<'a> {
441410 err. emit ( ) ;
442411 }
443412
444- return Ok ( bounds) ;
413+ Ok ( bounds)
445414 }
446415
447416 /// Can the current token begin a bound?
@@ -455,6 +424,58 @@ impl<'a> Parser<'a> {
455424 || self . check ( & token:: OpenDelim ( token:: Paren ) )
456425 }
457426
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+
458479 fn error_opt_out_lifetime ( & self , question : Option < Span > ) {
459480 if let Some ( span) = question {
460481 self . struct_span_err ( span, "`?` may only modify trait bounds, not lifetime bounds" )
0 commit comments