From 15bde57971226b82e398e8ea5d165f388279261c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 2 Sep 2023 22:31:30 -0700 Subject: [PATCH 1/2] Parse generic const items --- src/item.rs | 173 +++++++++++++++++++++++++++++----------------- tests/repo/mod.rs | 10 --- 2 files changed, 108 insertions(+), 75 deletions(-) diff --git a/src/item.rs b/src/item.rs index 50d7e6ef69..161286025b 100644 --- a/src/item.rs +++ b/src/item.rs @@ -985,23 +985,28 @@ pub(crate) mod parsing { } else { return Err(lookahead.error()); }; + let mut generics: Generics = input.parse()?; let colon_token = input.parse()?; let ty = input.parse()?; if input.peek(Token![;]) { input.parse::()?; Ok(Item::Verbatim(verbatim::between(&begin, input))) } else { + let eq_token: Token![=] = input.parse()?; + let expr: Expr = input.parse()?; + generics.where_clause = input.parse()?; + let semi_token: Token![;] = input.parse()?; Ok(Item::Const(ItemConst { attrs: Vec::new(), vis, const_token, ident, - generics: Generics::default(), + generics, colon_token, ty, - eq_token: input.parse()?, - expr: input.parse()?, - semi_token: input.parse()?, + eq_token, + expr: Box::new(expr), + semi_token, })) } } else if lookahead.peek(Token![unsafe]) { @@ -1400,24 +1405,36 @@ pub(crate) mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ItemConst { fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + let const_token: Token![const] = input.parse()?; + + let lookahead = input.lookahead1(); + let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) { + input.call(Ident::parse_any)? + } else { + return Err(lookahead.error()); + }; + + let mut generics: Generics = input.parse()?; + let colon_token: Token![:] = input.parse()?; + let ty: Type = input.parse()?; + let eq_token: Token![=] = input.parse()?; + let expr: Expr = input.parse()?; + generics.where_clause = input.parse()?; + let semi_token: Token![;] = input.parse()?; + Ok(ItemConst { - attrs: input.call(Attribute::parse_outer)?, - vis: input.parse()?, - const_token: input.parse()?, - ident: { - let lookahead = input.lookahead1(); - if lookahead.peek(Ident) || lookahead.peek(Token![_]) { - input.call(Ident::parse_any)? - } else { - return Err(lookahead.error()); - } - }, - generics: Generics::default(), - colon_token: input.parse()?, - ty: input.parse()?, - eq_token: input.parse()?, - expr: input.parse()?, - semi_token: input.parse()?, + attrs, + vis, + const_token, + ident, + generics, + colon_token, + ty: Box::new(ty), + eq_token, + expr: Box::new(expr), + semi_token, }) } } @@ -2273,30 +2290,38 @@ pub(crate) mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for TraitItemConst { fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let const_token: Token![const] = input.parse()?; + + let lookahead = input.lookahead1(); + let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) { + input.call(Ident::parse_any)? + } else { + return Err(lookahead.error()); + }; + + let mut generics: Generics = input.parse()?; + let colon_token: Token![:] = input.parse()?; + let ty: Type = input.parse()?; + let default = if input.peek(Token![=]) { + let eq_token: Token![=] = input.parse()?; + let default: Expr = input.parse()?; + Some((eq_token, default)) + } else { + None + }; + generics.where_clause = input.parse()?; + let semi_token: Token![;] = input.parse()?; + Ok(TraitItemConst { - attrs: input.call(Attribute::parse_outer)?, - const_token: input.parse()?, - ident: { - let lookahead = input.lookahead1(); - if lookahead.peek(Ident) || lookahead.peek(Token![_]) { - input.call(Ident::parse_any)? - } else { - return Err(lookahead.error()); - } - }, - generics: Generics::default(), - colon_token: input.parse()?, - ty: input.parse()?, - default: { - if input.peek(Token![=]) { - let eq_token: Token![=] = input.parse()?; - let default: Expr = input.parse()?; - Some((eq_token, default)) - } else { - None - } - }, - semi_token: input.parse()?, + attrs, + const_token, + ident, + generics, + colon_token, + ty, + default, + semi_token, }) } } @@ -2550,23 +2575,28 @@ pub(crate) mod parsing { } else { return Err(lookahead.error()); }; + let mut generics: Generics = input.parse()?; let colon_token: Token![:] = input.parse()?; let ty: Type = input.parse()?; if let Some(eq_token) = input.parse()? { + let expr: Expr = input.parse()?; + generics.where_clause = input.parse()?; + let semi_token: Token![;] = input.parse()?; return Ok(ImplItem::Const(ImplItemConst { attrs, vis, defaultness, const_token, ident, - generics: Generics::default(), + generics, colon_token, ty, eq_token, - expr: input.parse()?, - semi_token: input.parse()?, + expr, + semi_token, })); } else { + input.parse::>()?; input.parse::()?; return Ok(ImplItem::Verbatim(verbatim::between(&begin, input))); } @@ -2604,25 +2634,38 @@ pub(crate) mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ImplItemConst { fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + let defaultness: Option = input.parse()?; + let const_token: Token![const] = input.parse()?; + + let lookahead = input.lookahead1(); + let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) { + input.call(Ident::parse_any)? + } else { + return Err(lookahead.error()); + }; + + let mut generics: Generics = input.parse()?; + let colon_token: Token![:] = input.parse()?; + let ty: Type = input.parse()?; + let eq_token: Token![=] = input.parse()?; + let expr: Expr = input.parse()?; + generics.where_clause = input.parse()?; + let semi_token: Token![;] = input.parse()?; + Ok(ImplItemConst { - attrs: input.call(Attribute::parse_outer)?, - vis: input.parse()?, - defaultness: input.parse()?, - const_token: input.parse()?, - ident: { - let lookahead = input.lookahead1(); - if lookahead.peek(Ident) || lookahead.peek(Token![_]) { - input.call(Ident::parse_any)? - } else { - return Err(lookahead.error()); - } - }, - generics: Generics::default(), - colon_token: input.parse()?, - ty: input.parse()?, - eq_token: input.parse()?, - expr: input.parse()?, - semi_token: input.parse()?, + attrs, + vis, + defaultness, + const_token, + ident, + generics, + colon_token, + ty, + eq_token, + expr, + semi_token, }) } } diff --git a/tests/repo/mod.rs b/tests/repo/mod.rs index 8ae1ae2d44..980a85470e 100644 --- a/tests/repo/mod.rs +++ b/tests/repo/mod.rs @@ -17,16 +17,6 @@ const REVISION: &str = "9f5fc1bd443f59583e7af0d94d289f95fe1e20c4"; #[rustfmt::skip] static EXCLUDE_FILES: &[&str] = &[ - // TODO: generic const items - // https://github.com/dtolnay/syn/issues/1497 - "tests/rustdoc/generic-const-items.rs", - "tests/rustdoc/inline_cross/auxiliary/generic-const-items.rs", - "tests/ui/generic-const-items/associated-const-equality.rs", - "tests/ui/generic-const-items/basic.rs", - "tests/ui/generic-const-items/recursive.rs", - "tests/ui/object-safety/assoc_const_bounds.rs", - "tests/ui/object-safety/assoc_const_bounds_sized.rs", - // CStr literals (c"…") are not yet supported by rustc's lexer // https://github.com/rust-lang/rust/issues/113333 "src/tools/clippy/tests/ui/needless_raw_string_hashes.rs", From aafea03d649fc26e043f7d2db13db03d526036c5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 2 Sep 2023 22:44:10 -0700 Subject: [PATCH 2/2] Print generic const items --- src/item.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/item.rs b/src/item.rs index 161286025b..39a5f4cd1b 100644 --- a/src/item.rs +++ b/src/item.rs @@ -2877,10 +2877,12 @@ mod printing { self.vis.to_tokens(tokens); self.const_token.to_tokens(tokens); self.ident.to_tokens(tokens); + self.generics.to_tokens(tokens); self.colon_token.to_tokens(tokens); self.ty.to_tokens(tokens); self.eq_token.to_tokens(tokens); self.expr.to_tokens(tokens); + self.generics.where_clause.to_tokens(tokens); self.semi_token.to_tokens(tokens); } } @@ -3127,12 +3129,14 @@ mod printing { tokens.append_all(self.attrs.outer()); self.const_token.to_tokens(tokens); self.ident.to_tokens(tokens); + self.generics.to_tokens(tokens); self.colon_token.to_tokens(tokens); self.ty.to_tokens(tokens); if let Some((eq_token, default)) = &self.default { eq_token.to_tokens(tokens); default.to_tokens(tokens); } + self.generics.where_clause.to_tokens(tokens); self.semi_token.to_tokens(tokens); } } @@ -3193,10 +3197,12 @@ mod printing { self.defaultness.to_tokens(tokens); self.const_token.to_tokens(tokens); self.ident.to_tokens(tokens); + self.generics.to_tokens(tokens); self.colon_token.to_tokens(tokens); self.ty.to_tokens(tokens); self.eq_token.to_tokens(tokens); self.expr.to_tokens(tokens); + self.generics.where_clause.to_tokens(tokens); self.semi_token.to_tokens(tokens); } }