From 69663cd282539a9504fcb688330333f7111b9d19 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sat, 31 Jan 2026 18:12:13 +0100 Subject: [PATCH 1/3] Support implicit context type in `#[cgp_impl]` --- .../cgp-macro-lib/src/entrypoints/cgp_impl.rs | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs b/crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs index 20794034..d78939bc 100644 --- a/crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs +++ b/crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs @@ -2,9 +2,8 @@ use proc_macro2::{Span, TokenStream}; use quote::{ToTokens, quote}; use syn::parse::discouraged::Speculative; use syn::parse::{Parse, ParseStream}; -use syn::spanned::Spanned; use syn::token::{Colon, For}; -use syn::{Error, FnArg, Ident, ImplItem, ItemImpl, Type, parse2}; +use syn::{FnArg, Ident, ImplItem, ItemImpl, Type, parse_quote, parse2}; use crate::derive_provider::{ derive_component_name_from_provider_impl, derive_is_provider_for, derive_provider_struct, @@ -18,16 +17,28 @@ pub fn cgp_impl(attr: TokenStream, body: TokenStream) -> syn::Result { + let consumer_trait_path = parse2(path.to_token_stream())?; + let context_type = item_impl.self_ty.as_ref(); + transform_impl_trait( + &item_impl, + &consumer_trait_path, + &spec.provider_type, + context_type, + )? + } + None => { + let consumer_trait_path = parse2(item_impl.self_ty.to_token_stream())?; + let context_type = parse_quote! { __Context__ }; + transform_impl_trait( + &item_impl, + &consumer_trait_path, + &spec.provider_type, + &context_type, + )? + } + }; let component_type = match &spec.component_type { Some(component_type) => component_type.clone(), @@ -92,9 +103,8 @@ pub fn transform_impl_trait( item_impl: &ItemImpl, consumer_trait_path: &SimpleType, provider_type: &Type, + context_type: &Type, ) -> syn::Result { - let context_type = item_impl.self_ty.as_ref(); - let context_var = if let Ok(ident) = parse2::(context_type.to_token_stream()) { to_snake_case_ident(&ident) } else { From 609d6c0bc81e01ade1e0c686e72c97ef45dd2cbb Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sat, 31 Jan 2026 18:15:59 +0100 Subject: [PATCH 2/3] Add tests --- .../cgp-macro-lib/src/entrypoints/cgp_impl.rs | 8 ++- .../cgp_impl/implicit_context.rs | 50 +++++++++++++++++++ .../tests/component_tests/cgp_impl/mod.rs | 1 + rust-toolchain.toml | 2 +- 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 crates/cgp-tests/tests/component_tests/cgp_impl/implicit_context.rs diff --git a/crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs b/crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs index d78939bc..b2652d0e 100644 --- a/crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs +++ b/crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs @@ -15,7 +15,7 @@ use crate::replace_self::{ pub fn cgp_impl(attr: TokenStream, body: TokenStream) -> syn::Result { let spec: ImplProviderSpec = parse2(attr)?; - let item_impl: ItemImpl = parse2(body)?; + let mut item_impl: ItemImpl = parse2(body)?; let provider_impl = match &item_impl.trait_ { Some((_, path, _)) => { @@ -31,6 +31,12 @@ pub fn cgp_impl(attr: TokenStream, body: TokenStream) -> syn::Result { let consumer_trait_path = parse2(item_impl.self_ty.to_token_stream())?; let context_type = parse_quote! { __Context__ }; + + item_impl + .generics + .params + .insert(0, parse_quote! { __Context__ }); + transform_impl_trait( &item_impl, &consumer_trait_path, diff --git a/crates/cgp-tests/tests/component_tests/cgp_impl/implicit_context.rs b/crates/cgp-tests/tests/component_tests/cgp_impl/implicit_context.rs new file mode 100644 index 00000000..e822ee7d --- /dev/null +++ b/crates/cgp-tests/tests/component_tests/cgp_impl/implicit_context.rs @@ -0,0 +1,50 @@ +use cgp::prelude::*; + +#[cgp_component(FooProvider)] +pub trait CanDoFoo { + fn foo(&self, value: u32) -> String; +} + +#[cgp_auto_getter] +pub trait HasName { + fn name(&self) -> &str; +} + +#[cgp_impl(new ValueToString)] +impl FooProvider { + fn foo(&self, value: u32) -> String { + value.to_string() + } +} + +pub mod inner { + use core::fmt::Display; + + use cgp::prelude::*; + + use super::{FooProvider, FooProviderComponent, HasName}; + + #[cgp_impl(new WithNamePrefix)] + impl FooProvider + where + Self: HasName, + { + fn foo(&self, value: u32) -> String { + format!("{}: {}", self.name(), value) + } + } + + pub struct Foo { + pub tag: Tag, + } + + #[cgp_impl(new WithFooTag: FooProviderComponent)] + impl FooProvider for Foo + where + Tag: Display, + { + fn foo(&self, value: u32) -> String { + format!("{}: {}", self.tag, value) + } + } +} diff --git a/crates/cgp-tests/tests/component_tests/cgp_impl/mod.rs b/crates/cgp-tests/tests/component_tests/cgp_impl/mod.rs index 38883ee0..a1da2f99 100644 --- a/crates/cgp-tests/tests/component_tests/cgp_impl/mod.rs +++ b/crates/cgp-tests/tests/component_tests/cgp_impl/mod.rs @@ -1 +1,2 @@ pub mod basic; +pub mod implicit_context; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 29b05176..9c144613 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.90" +channel = "1.93" profile = "default" From f01ab2e70086ebef9b85a4fd62bcf9944c037e23 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sat, 31 Jan 2026 18:21:10 +0100 Subject: [PATCH 3/3] Fix clippy --- .../cgp-extra-macro-lib/src/entrypoints/cgp_auto_dispatch.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cgp-extra-macro-lib/src/entrypoints/cgp_auto_dispatch.rs b/crates/cgp-extra-macro-lib/src/entrypoints/cgp_auto_dispatch.rs index c09b4e77..37e8257d 100644 --- a/crates/cgp-extra-macro-lib/src/entrypoints/cgp_auto_dispatch.rs +++ b/crates/cgp-extra-macro-lib/src/entrypoints/cgp_auto_dispatch.rs @@ -100,13 +100,13 @@ fn derive_blanket_impl(item_trait: &ItemTrait) -> syn::Result { if let FnArg::Typed(pat_type) = arg { let arg_ident = Ident::new(&format!("arg_{}", i), pat_type.span()); arg_idents.push(arg_ident.clone()); - pat_type.pat = Box::new(Pat::Ident(PatIdent { + *pat_type.pat = Pat::Ident(PatIdent { ident: arg_ident, attrs: Default::default(), by_ref: Default::default(), mutability: Default::default(), subpat: Default::default(), - })); + }); let mut arg_type = pat_type.ty.as_ref().clone(); if let Type::Reference(arg_type) = &mut arg_type {