From b5aabc5b03c31bc6f24f841798058947079f48d6 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 2 Sep 2023 22:09:12 -0700 Subject: [PATCH] Support unnamed struct/union type syntax --- Cargo.toml | 4 ++-- src/ty.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 91e6d8b..a37df59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,10 @@ verbatim = ["syn/parsing"] [dependencies] proc-macro2 = { version = "1.0.63", default-features = false } -syn = { version = "2.0.23", default-features = false, features = ["full"] } +syn = { version = "2.0.30", default-features = false, features = ["full"] } [dev-dependencies] -syn = { version = "2.0.23", default-features = false, features = ["parsing"] } +syn = { version = "2.0.30", default-features = false, features = ["parsing"] } [lib] doc-scrape-examples = false diff --git a/src/ty.rs b/src/ty.rs index f4c24f6..6576a18 100644 --- a/src/ty.rs +++ b/src/ty.rs @@ -171,15 +171,25 @@ impl Printer { fn type_verbatim(&mut self, tokens: &TokenStream) { use syn::parse::{Parse, ParseStream, Result}; use syn::punctuated::Punctuated; - use syn::{Token, TypeParamBound}; + use syn::{token, FieldsNamed, Token, TypeParamBound}; enum TypeVerbatim { Ellipsis, + AnonStruct(AnonStruct), + AnonUnion(AnonUnion), DynStar(DynStar), MutSelf(MutSelf), NotType(NotType), } + struct AnonStruct { + fields: FieldsNamed, + } + + struct AnonUnion { + fields: FieldsNamed, + } + struct DynStar { bounds: Punctuated, } @@ -195,7 +205,15 @@ impl Printer { impl Parse for TypeVerbatim { fn parse(input: ParseStream) -> Result { let lookahead = input.lookahead1(); - if lookahead.peek(Token![dyn]) { + if lookahead.peek(Token![struct]) { + input.parse::()?; + let fields: FieldsNamed = input.parse()?; + Ok(TypeVerbatim::AnonStruct(AnonStruct { fields })) + } else if lookahead.peek(Token![union]) && input.peek2(token::Brace) { + input.parse::()?; + let fields: FieldsNamed = input.parse()?; + Ok(TypeVerbatim::AnonUnion(AnonUnion { fields })) + } else if lookahead.peek(Token![dyn]) { input.parse::()?; input.parse::()?; let bounds = input.parse_terminated(TypeParamBound::parse, Token![+])?; @@ -233,6 +251,32 @@ impl Printer { TypeVerbatim::Ellipsis => { self.word("..."); } + TypeVerbatim::AnonStruct(ty) => { + self.cbox(INDENT); + self.word("struct {"); + self.hardbreak_if_nonempty(); + for field in &ty.fields.named { + self.field(field); + self.word(","); + self.hardbreak(); + } + self.offset(-INDENT); + self.end(); + self.word("}"); + } + TypeVerbatim::AnonUnion(ty) => { + self.cbox(INDENT); + self.word("union {"); + self.hardbreak_if_nonempty(); + for field in &ty.fields.named { + self.field(field); + self.word(","); + self.hardbreak(); + } + self.offset(-INDENT); + self.end(); + self.word("}"); + } TypeVerbatim::DynStar(ty) => { self.word("dyn* "); for type_param_bound in ty.bounds.iter().delimited() {