From a7ee91ace2edfdf4279e00a45f2e22dc9cf9672b Mon Sep 17 00:00:00 2001 From: Arnaud de Bossoreille Date: Wed, 30 Oct 2024 08:29:10 +0100 Subject: [PATCH] Use syn visitor to rewrite types --- .github/workflows/ci.yml | 7 -- truc/Cargo.toml | 7 +- truc/src/lib.rs | 1 - truc/src/record/type_name.rs | 201 ++++++++++++----------------------- 4 files changed, 71 insertions(+), 145 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7e6cb1..41211eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,6 @@ jobs: uses: ./.github/workflows/_build.yml with: rust_toolchain: stable - rust_features: --features "full" with_rustfmt: true main_1_56_1: @@ -19,7 +18,6 @@ jobs: uses: ./.github/workflows/_build.yml with: rust_toolchain: 1.56.1 - rust_features: --features "full" with_clippy: true pre_build_script: ./scripts/msrv_pin_dependencies.sh @@ -28,7 +26,6 @@ jobs: uses: ./.github/workflows/_build.yml with: rust_toolchain: nightly - rust_features: --all-features cross_stable_i686: name: Rust stable i686-unknown-linux-gnu @@ -36,7 +33,6 @@ jobs: with: target: i686-unknown-linux-gnu rust_toolchain: stable - rust_features: --features "full" cross_stable_aarch64: name: Rust stable aarch64-unknown-linux-gnu @@ -44,7 +40,6 @@ jobs: with: target: aarch64-unknown-linux-gnu rust_toolchain: stable - rust_features: --features "full" cross_1_65_0_i686: name: Rust 1.65.0 i686-unknown-linux-gnu @@ -52,7 +47,6 @@ jobs: with: target: i686-unknown-linux-gnu rust_toolchain: 1.65.0 - rust_features: --features "full" cross_1_65_0_aarch64: name: Rust 1.65.0 aarch64-unknown-linux-gnu @@ -60,5 +54,4 @@ jobs: with: target: aarch64-unknown-linux-gnu rust_toolchain: 1.65.0 - rust_features: --features "full" diff --git a/truc/Cargo.toml b/truc/Cargo.toml index 16128a6..bb9d4ec 100644 --- a/truc/Cargo.toml +++ b/truc/Cargo.toml @@ -18,17 +18,12 @@ proc-macro2 = "1" quote = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" -syn = { version = "1", features = ["full", "extra-traits"] } +syn = { version = "1", features = ["full", "extra-traits", "visit-mut"] } truc_runtime = { version = "0.1.2-dev", path = "../truc_runtime" } [dev-dependencies] rand = "0.8" rand_chacha = "0.3" -[features] -full = [] -full_unstable = ["unstable"] -unstable = [] - [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage,coverage_nightly)'] } diff --git a/truc/src/lib.rs b/truc/src/lib.rs index 8266b75..4bd4d51 100644 --- a/truc/src/lib.rs +++ b/truc/src/lib.rs @@ -1,5 +1,4 @@ #![cfg_attr(test, allow(clippy::many_single_char_names))] -#![cfg_attr(feature = "unstable", feature(non_exhaustive_omitted_patterns_lint))] #![cfg_attr(coverage_nightly, feature(coverage_attribute))] #[macro_use] diff --git a/truc/src/record/type_name.rs b/truc/src/record/type_name.rs index 1d63048..fb61d90 100644 --- a/truc/src/record/type_name.rs +++ b/truc/src/record/type_name.rs @@ -1,8 +1,11 @@ +use syn::{ + visit_mut::{visit_type_path_mut, VisitMut}, + Path, TypePath, +}; + pub fn truc_type_name() -> String { let std_type_name = std::any::type_name::(); - let mut syn_type = syn::parse_str::(std_type_name).expect("syn type"); - rewrite_type(&mut syn_type); - quote!(#syn_type).to_string() + truc_dynamic_type_name(std_type_name) } pub fn truc_dynamic_type_name(type_name: &str) -> String { @@ -12,158 +15,94 @@ pub fn truc_dynamic_type_name(type_name: &str) -> String { } fn rewrite_type(syn_type: &mut syn::Type) { - #[cfg_attr(all(test, feature = "unstable"), deny(non_exhaustive_omitted_patterns))] - match syn_type { - syn::Type::Array(syn::TypeArray { - bracket_token: _, - elem, - semi_token: _, - len: _, - }) => { - rewrite_type(elem); - } - syn::Type::BareFn(_) - | syn::Type::Group(_) - | syn::Type::ImplTrait(_) - | syn::Type::Infer(_) - | syn::Type::Macro(_) - | syn::Type::Never(_) => { - unimplemented!("{:?}", syn_type); - } - syn::Type::Paren(syn::TypeParen { - paren_token: _, - elem, - }) => { - rewrite_type(elem); - } - syn::Type::Path(syn::TypePath { + TypeRewriter.visit_type_mut(syn_type); +} + +struct TypeRewriter; + +impl VisitMut for TypeRewriter { + fn visit_type_path_mut(&mut self, i: &mut TypePath) { + let TypePath { qself: _, - path: syn::Path { + path: Path { leading_colon, segments, }, - }) => { - let mut matched; + } = i; + let mut matched; + matched = { + leading_colon.is_none() && { + let mut seg_iter = segments.iter_mut(); + match_segment(seg_iter.next(), "alloc", || { + match_segment(seg_iter.next(), "string", || { + match_segment(seg_iter.next(), "String", || seg_iter.next().is_none()) + }) + }) + } + }; + if matched { + let mut seg = segments.pop().expect("segment").into_value(); + seg.ident = syn::Ident::new("String", proc_macro2::Span::call_site()); + segments.clear(); + segments.push(seg); + } + if !matched { matched = { leading_colon.is_none() && { let mut seg_iter = segments.iter_mut(); match_segment(seg_iter.next(), "alloc", || { - match_segment(seg_iter.next(), "string", || { - match_segment(seg_iter.next(), "String", || seg_iter.next().is_none()) + match_segment(seg_iter.next(), "boxed", || { + match_segment_with_arguments(seg_iter.next(), "Box", || { + seg_iter.next().is_none() + }) }) }) } }; if matched { let mut seg = segments.pop().expect("segment").into_value(); - seg.ident = syn::Ident::new("String", proc_macro2::Span::call_site()); + seg.ident = syn::Ident::new("Box", proc_macro2::Span::call_site()); segments.clear(); segments.push(seg); } - if !matched { - matched = { - leading_colon.is_none() && { - let mut seg_iter = segments.iter_mut(); - match_segment(seg_iter.next(), "alloc", || { - match_segment(seg_iter.next(), "boxed", || { - match_segment_with_arguments(seg_iter.next(), "Box", || { - seg_iter.next().is_none() - }) - }) - }) - } - }; - if matched { - let mut seg = segments.pop().expect("segment").into_value(); - seg.ident = syn::Ident::new("Box", proc_macro2::Span::call_site()); - segments.clear(); - segments.push(seg); - } - } - if !matched { - matched = leading_colon.is_none() && { - let mut seg_iter = segments.iter_mut(); - match_segment(seg_iter.next(), "core", || { - match_segment(seg_iter.next(), "option", || { - match_segment_with_arguments(seg_iter.next(), "Option", || { - seg_iter.next().is_none() - }) + } + if !matched { + matched = leading_colon.is_none() && { + let mut seg_iter = segments.iter_mut(); + match_segment(seg_iter.next(), "core", || { + match_segment(seg_iter.next(), "option", || { + match_segment_with_arguments(seg_iter.next(), "Option", || { + seg_iter.next().is_none() }) }) - }; - if matched { - let mut seg = segments.pop().expect("segment").into_value(); - seg.ident = syn::Ident::new("Option", proc_macro2::Span::call_site()); - segments.clear(); - segments.push(seg); - } + }) + }; + if matched { + let mut seg = segments.pop().expect("segment").into_value(); + seg.ident = syn::Ident::new("Option", proc_macro2::Span::call_site()); + segments.clear(); + segments.push(seg); } - if !matched { - matched = leading_colon.is_none() && { - let mut seg_iter = segments.iter_mut(); - match_segment(seg_iter.next(), "core", || { - match_segment(seg_iter.next(), "result", || { - match_segment_with_arguments(seg_iter.next(), "Result", || { - seg_iter.next().is_none() - }) + } + if !matched { + matched = leading_colon.is_none() && { + let mut seg_iter = segments.iter_mut(); + match_segment(seg_iter.next(), "core", || { + match_segment(seg_iter.next(), "result", || { + match_segment_with_arguments(seg_iter.next(), "Result", || { + seg_iter.next().is_none() }) }) - }; - if matched { - let mut seg = segments.pop().expect("segment").into_value(); - seg.ident = syn::Ident::new("Result", proc_macro2::Span::call_site()); - segments.clear(); - segments.push(seg); - } - } - for seg in segments.iter_mut() { - match &mut seg.arguments { - syn::PathArguments::None => {} - syn::PathArguments::AngleBracketed(args) => { - for arg in &mut args.args { - match arg { - syn::GenericArgument::Lifetime(_) => {} - syn::GenericArgument::Type(r#type) => rewrite_type(r#type), - syn::GenericArgument::Binding(_) => {} - syn::GenericArgument::Constraint(_) => {} - syn::GenericArgument::Const(_) => {} - } - } - } - syn::PathArguments::Parenthesized(args) => { - for r#type in &mut args.inputs { - rewrite_type(r#type) - } - } - } - } - } - syn::Type::Ptr(_) | syn::Type::Reference(_) => { - unimplemented!("{:?}", syn_type); - } - syn::Type::Slice(syn::TypeSlice { - bracket_token: _, - elem, - }) => { - rewrite_type(elem); - } - syn::Type::TraitObject(_) => { - unimplemented!("{:?}", syn_type); - } - syn::Type::Tuple(syn::TypeTuple { - paren_token: _, - elems, - }) => { - for r#type in &mut elems.iter_mut() { - rewrite_type(r#type) + }) + }; + if matched { + let mut seg = segments.pop().expect("segment").into_value(); + seg.ident = syn::Ident::new("Result", proc_macro2::Span::call_site()); + segments.clear(); + segments.push(seg); } } - syn::Type::Verbatim(_) => { - unimplemented!("{:?}", syn_type); - } - _ => { - unimplemented!("{:?}", syn_type); - } + visit_type_path_mut(self, i); } }