Skip to content

Commit 8a9a992

Browse files
committed
extract parse_generic_bound
1 parent fd89104 commit 8a9a992

File tree

1 file changed

+61
-40
lines changed
  • src/librustc_parse/parser

1 file changed

+61
-40
lines changed

src/librustc_parse/parser/ty.rs

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)