From 0f99d27656d31f8e87e70ccd0262d17ce2e580c5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 24 Mar 2023 10:37:08 -0700 Subject: [PATCH] Factor out some common code for type parsing --- src/item.rs | 78 +++++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/src/item.rs b/src/item.rs index 878d70d447..3c432a1db1 100644 --- a/src/item.rs +++ b/src/item.rs @@ -1103,21 +1103,7 @@ pub(crate) mod parsing { let type_token: Token![type] = input.parse()?; let ident: Ident = input.parse()?; let mut generics: Generics = input.parse()?; - let colon_token: Option = input.parse()?; - - let mut bounds = Punctuated::new(); - if colon_token.is_some() { - loop { - if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) { - break; - } - bounds.push_value(input.parse::()?); - if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) { - break; - } - bounds.push_punct(input.parse::()?); - } - } + let (colon_token, bounds) = Self::parse_optional_bounds(input)?; match where_clause_location { WhereClauseLocation::BeforeEq | WhereClauseLocation::Both => { @@ -1126,11 +1112,7 @@ pub(crate) mod parsing { WhereClauseLocation::AfterEq => {} } - let ty = if let Some(eq_token) = input.parse()? { - Some((eq_token, input.parse::()?)) - } else { - None - }; + let ty = Self::parse_optional_definition(input)?; match where_clause_location { WhereClauseLocation::AfterEq | WhereClauseLocation::Both @@ -1155,6 +1137,38 @@ pub(crate) mod parsing { semi_token, }) } + + fn parse_optional_bounds( + input: ParseStream, + ) -> Result<(Option, Punctuated)> { + let colon_token: Option = input.parse()?; + + let mut bounds = Punctuated::new(); + if colon_token.is_some() { + loop { + if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) { + break; + } + bounds.push_value(input.parse::()?); + if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) { + break; + } + bounds.push_punct(input.parse::()?); + } + } + + Ok((colon_token, bounds)) + } + + fn parse_optional_definition(input: ParseStream) -> Result> { + let eq_token: Option = input.parse()?; + if let Some(eq_token) = eq_token { + let definition: Type = input.parse()?; + Ok(Some((eq_token, definition))) + } else { + Ok(None) + } + } } #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] @@ -2310,30 +2324,10 @@ pub(crate) mod parsing { let type_token: Token![type] = input.parse()?; let ident: Ident = input.parse()?; let mut generics: Generics = input.parse()?; - let colon_token: Option = input.parse()?; - - let mut bounds = Punctuated::new(); - if colon_token.is_some() { - while !input.peek(Token![where]) && !input.peek(Token![=]) && !input.peek(Token![;]) - { - if !bounds.is_empty() { - bounds.push_punct(input.parse()?); - } - bounds.push_value(input.parse()?); - } - } - - let default = if input.peek(Token![=]) { - let eq_token: Token![=] = input.parse()?; - let default: Type = input.parse()?; - Some((eq_token, default)) - } else { - None - }; - + let (colon_token, bounds) = FlexibleItemType::parse_optional_bounds(input)?; + let default = FlexibleItemType::parse_optional_definition(input)?; generics.where_clause = input.parse()?; let semi_token: Token![;] = input.parse()?; - Ok(TraitItemType { attrs, type_token,