From 1c2948f812ae6df021b17f7007d4fe92be6b1114 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Wed, 18 Feb 2026 00:06:27 +0100 Subject: [PATCH 1/5] Apply abstract type alias to other trait bounds --- crates/cgp-macro-lib/src/cgp_fn/item_impl.rs | 32 +++++++++++++------ crates/cgp-macro-lib/src/cgp_fn/item_trait.rs | 22 +++++-------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/crates/cgp-macro-lib/src/cgp_fn/item_impl.rs b/crates/cgp-macro-lib/src/cgp_fn/item_impl.rs index 622a803f..ebef39e1 100644 --- a/crates/cgp-macro-lib/src/cgp_fn/item_impl.rs +++ b/crates/cgp-macro-lib/src/cgp_fn/item_impl.rs @@ -28,11 +28,23 @@ pub fn derive_item_impl( .params .insert(0, parse2(quote! { __Context__ })?); - let mut bounds: Punctuated = Punctuated::default(); - bounds.extend(attributes.extend.clone()); + { + let mut bounds: Punctuated = Punctuated::default(); + bounds.extend(attributes.extend.clone()); + + for import in attributes.uses.iter() { + bounds.push(parse2(quote! { #import })?); + } - for import in attributes.uses.iter() { - bounds.push(parse2(quote! { #import })?); + if !bounds.is_empty() { + item_impl + .generics + .make_where_clause() + .predicates + .push(parse2(quote! { + Self: #bounds + })?); + } } { @@ -56,18 +68,18 @@ pub fn derive_item_impl( } if !attributes.use_type.is_empty() { - for use_type in attributes.use_type.iter() { - bounds.push(parse2(use_type.trait_path.to_token_stream())?); - } - item_impl = parse2(substitute_abstract_type( "e! { Self }, &attributes.use_type, item_impl.to_token_stream(), ))?; - } - if !bounds.is_empty() { + let mut bounds: Punctuated = Punctuated::default(); + + for use_type in attributes.use_type.iter() { + bounds.push(parse2(use_type.trait_path.to_token_stream())?); + } + item_impl .generics .make_where_clause() diff --git a/crates/cgp-macro-lib/src/cgp_fn/item_trait.rs b/crates/cgp-macro-lib/src/cgp_fn/item_trait.rs index ea36ea2b..cdd89520 100644 --- a/crates/cgp-macro-lib/src/cgp_fn/item_trait.rs +++ b/crates/cgp-macro-lib/src/cgp_fn/item_trait.rs @@ -1,7 +1,5 @@ use quote::{ToTokens, quote}; -use syn::punctuated::Punctuated; -use syn::token::Plus; -use syn::{Generics, Ident, ItemFn, ItemTrait, TraitItemFn, TypeParamBound, parse2}; +use syn::{Generics, Ident, ItemFn, ItemTrait, TraitItemFn, parse2}; use crate::cgp_fn::{FunctionAttributes, substitute_abstract_type}; @@ -26,25 +24,21 @@ pub fn derive_item_trait( } })?; - let mut bounds: Punctuated = Punctuated::default(); - - for extend in &attributes.extend { - bounds.push(extend.clone()); - } + item_trait.supertraits.extend(attributes.extend.clone()); if !attributes.use_type.is_empty() { - for use_type in attributes.use_type.iter() { - bounds.push(parse2(use_type.trait_path.to_token_stream())?); - } - item_trait = parse2(substitute_abstract_type( "e! { Self }, &attributes.use_type, item_trait.to_token_stream(), ))?; - } - item_trait.supertraits.extend(bounds); + for use_type in attributes.use_type.iter() { + item_trait + .supertraits + .push(parse2(use_type.trait_path.to_token_stream())?); + } + } Ok(item_trait) } From 3f514f0eb613cc623df5c249ba0d5fadfff4ed89 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Wed, 18 Feb 2026 10:28:15 +0100 Subject: [PATCH 2/5] Allow only one mutable implicit argument --- crates/cgp-macro-lib/src/cgp_fn/derive.rs | 9 ++- .../src/cgp_fn/parse_implicits.rs | 73 ++++++++++++------- .../src/derive_getter/blanket.rs | 2 +- .../src/derive_getter/getter_field.rs | 2 +- .../cgp-macro-lib/src/derive_getter/method.rs | 8 +- .../cgp-macro-lib/src/derive_getter/parse.rs | 16 ++-- .../src/derive_getter/use_field.rs | 2 +- .../src/derive_getter/use_fields.rs | 2 +- .../src/derive_getter/with_provider.rs | 2 +- 9 files changed, 70 insertions(+), 46 deletions(-) diff --git a/crates/cgp-macro-lib/src/cgp_fn/derive.rs b/crates/cgp-macro-lib/src/cgp_fn/derive.rs index 160b026b..85fe16af 100644 --- a/crates/cgp-macro-lib/src/cgp_fn/derive.rs +++ b/crates/cgp-macro-lib/src/cgp_fn/derive.rs @@ -20,17 +20,18 @@ pub fn derive_cgp_fn(trait_ident: &Ident, mut item_fn: ItemFn) -> syn::Result syn::Result, ) -> syn::Result> { - let mut implicit_args = Vec::new(); - - let process_args = mem::take(args); + let implicit_fn_args = extract_implicit_args(args); - for mut arg in process_args.into_iter() { - if let Some(implicit_arg) = try_parse_implicit_arg(receiver, &mut arg)? { - implicit_args.push(implicit_arg); - } else { - args.push(arg); - } + if receiver.mutability.is_some() && implicit_fn_args.len() > 1 { + return Err(syn::Error::new_spanned( + &args, + "Only one mutable implicit argument is allowed when self is mutable", + )); } - Ok(implicit_args) -} + let mut implicit_args = Vec::new(); -pub fn try_parse_implicit_arg( - receiver: &Receiver, - arg: &mut FnArg, -) -> syn::Result> { - if let FnArg::Typed(arg) = arg { - let attrs = mem::take(&mut arg.attrs); - for attr in attrs { - if is_implicit_attr(&attr) { - let spec = parse_implicit_arg(receiver, arg)?; - return Ok(Some(spec)); - } else { - arg.attrs.push(attr); - } - } + for arg in implicit_fn_args { + let spec = parse_implicit_arg(receiver, &arg)?; + implicit_args.push(spec); } - Ok(None) + Ok(implicit_args) } pub fn parse_implicit_arg(receiver: &Receiver, arg: &PatType) -> syn::Result { @@ -65,6 +50,42 @@ pub fn parse_implicit_arg(receiver: &Receiver, arg: &PatType) -> syn::Result) -> Vec { + let mut implicit_args = Vec::new(); + + let process_args = mem::take(args); + + for arg in process_args.into_iter() { + if let FnArg::Typed(mut arg) = arg { + if is_implicit_arg(&mut arg) { + implicit_args.push(arg); + } else { + args.push(FnArg::Typed(arg)); + } + } else { + args.push(arg); + } + } + + implicit_args +} + +pub fn is_implicit_arg(arg: &mut PatType) -> bool { + let mut res = false; + + let attrs = mem::take(&mut arg.attrs); + + for attr in attrs { + if is_implicit_attr(&attr) { + res = true; + } else { + arg.attrs.push(attr); + } + } + + res +} + pub fn is_implicit_attr(attr: &Attribute) -> bool { match &attr.meta { Meta::Path(path) => path.is_ident("implicit"), diff --git a/crates/cgp-macro-lib/src/derive_getter/blanket.rs b/crates/cgp-macro-lib/src/derive_getter/blanket.rs index 85406929..e067a095 100644 --- a/crates/cgp-macro-lib/src/derive_getter/blanket.rs +++ b/crates/cgp-macro-lib/src/derive_getter/blanket.rs @@ -76,7 +76,7 @@ pub fn derive_blanket_impl( let constraint = derive_getter_constraint( &field.field_type, - &field.field_mut, + &field.receiver_mut, &field.field_mode, quote! { #field_symbol }, &field_assoc_type.as_ref().map(|item| item.ident.clone()), diff --git a/crates/cgp-macro-lib/src/derive_getter/getter_field.rs b/crates/cgp-macro-lib/src/derive_getter/getter_field.rs index e252a595..8fec551f 100644 --- a/crates/cgp-macro-lib/src/derive_getter/getter_field.rs +++ b/crates/cgp-macro-lib/src/derive_getter/getter_field.rs @@ -5,7 +5,7 @@ pub struct GetterField { pub field_name: Ident, pub field_type: Type, pub return_type: Type, - pub field_mut: Option, + pub receiver_mut: Option, pub phantom_arg_type: Option, pub field_mode: FieldMode, pub receiver_mode: ReceiverMode, diff --git a/crates/cgp-macro-lib/src/derive_getter/method.rs b/crates/cgp-macro-lib/src/derive_getter/method.rs index d2120034..899ca29e 100644 --- a/crates/cgp-macro-lib/src/derive_getter/method.rs +++ b/crates/cgp-macro-lib/src/derive_getter/method.rs @@ -29,14 +29,14 @@ pub fn derive_getter_method( let context_fn_arg = match &context_arg { ContextArg::SelfArg => { - if spec.field_mut.is_none() { + if spec.receiver_mut.is_none() { quote! { &self } } else { quote! { &mut self } } } ContextArg::Ident(context_type) => { - if spec.field_mut.is_none() { + if spec.receiver_mut.is_none() { quote! { context: & #context_type} } else { quote! { context: &mut #context_type } @@ -44,7 +44,7 @@ pub fn derive_getter_method( } }; - let get_field_method = if spec.field_mut.is_none() { + let get_field_method = if spec.receiver_mut.is_none() { quote! { get_field } } else { quote! { get_field_mut } @@ -72,7 +72,7 @@ pub fn derive_getter_method( } }; - let call_expr = extend_call_expr(call_expr, &spec.field_mode, &spec.field_mut); + let call_expr = extend_call_expr(call_expr, &spec.field_mode, &spec.receiver_mut); let return_type = &spec.return_type; diff --git a/crates/cgp-macro-lib/src/derive_getter/parse.rs b/crates/cgp-macro-lib/src/derive_getter/parse.rs index a57a6d43..8f272b94 100644 --- a/crates/cgp-macro-lib/src/derive_getter/parse.rs +++ b/crates/cgp-macro-lib/src/derive_getter/parse.rs @@ -103,18 +103,18 @@ pub fn parse_getter_method( let (arg, phantom) = parse_method_args(&signature.inputs)?; - let (receiver_mode, field_mut) = parse_receiver(context_type, arg)?; + let (receiver_mode, receiver_mut) = parse_receiver(context_type, arg)?; let return_type = parse_return_type(context_type, &signature.output, field_assoc_type)?; - let (field_type, field_mode) = parse_field_type(&return_type, &field_mut)?; + let (field_type, field_mode) = parse_field_type(&return_type, &receiver_mut)?; Ok(GetterField { receiver_mode, field_name, field_type, return_type, - field_mut, + receiver_mut, phantom_arg_type: phantom, field_mode, }) @@ -263,15 +263,15 @@ fn parse_return_type( pub fn parse_field_type( return_type: &Type, - field_mut: &Option, + receiver_mut: &Option, ) -> syn::Result<(Type, FieldMode)> { match &return_type { Type::Reference(type_ref) => { - if type_ref.mutability.is_some() != field_mut.is_some() { + if type_ref.mutability.is_some() && receiver_mut.is_none() { return Err(Error::new( type_ref.span(), format!( - "field type `{}` must have the same mutability as the self reference", + "&mut self is required for mutable field reference `{}`", type_ref.to_token_stream() ), )); @@ -283,7 +283,7 @@ pub fn parse_field_type( let field_type: Type = parse_quote! { String }; Ok((field_type, FieldMode::Str)) - } else if let (Type::Slice(slice), None) = (type_ref.elem.as_ref(), field_mut) { + } else if let (Type::Slice(slice), None) = (type_ref.elem.as_ref(), receiver_mut) { let field_type = slice.elem.as_ref().clone(); Ok((field_type, FieldMode::Slice)) @@ -299,7 +299,7 @@ pub fn parse_field_type( parse2(quote! { Option< #field_type > })?, FieldMode::OptionRef, )) - } else if let (Some(field_type), None) = (try_parse_mref(type_path), field_mut) { + } else if let (Some(field_type), None) = (try_parse_mref(type_path), receiver_mut) { Ok((field_type.clone(), FieldMode::MRef)) } else { Ok((return_type.clone(), FieldMode::Clone)) diff --git a/crates/cgp-macro-lib/src/derive_getter/use_field.rs b/crates/cgp-macro-lib/src/derive_getter/use_field.rs index 333f145a..661e98f4 100644 --- a/crates/cgp-macro-lib/src/derive_getter/use_field.rs +++ b/crates/cgp-macro-lib/src/derive_getter/use_field.rs @@ -62,7 +62,7 @@ pub fn derive_use_field_impl( let constraint = derive_getter_constraint( &field.field_type, - &field.field_mut, + &field.receiver_mut, &field.field_mode, quote! { #tag_type }, &field_assoc_type.as_ref().map(|item| item.ident.clone()), diff --git a/crates/cgp-macro-lib/src/derive_getter/use_fields.rs b/crates/cgp-macro-lib/src/derive_getter/use_fields.rs index 3e14031f..9ebdb81e 100644 --- a/crates/cgp-macro-lib/src/derive_getter/use_fields.rs +++ b/crates/cgp-macro-lib/src/derive_getter/use_fields.rs @@ -67,7 +67,7 @@ pub fn derive_use_fields_impl( let constraint = derive_getter_constraint( &field.field_type, - &field.field_mut, + &field.receiver_mut, &field.field_mode, quote! { #field_symbol }, &field_assoc_type.as_ref().map(|item| item.ident.clone()), diff --git a/crates/cgp-macro-lib/src/derive_getter/with_provider.rs b/crates/cgp-macro-lib/src/derive_getter/with_provider.rs index ee7c2fe5..30a1d0d5 100644 --- a/crates/cgp-macro-lib/src/derive_getter/with_provider.rs +++ b/crates/cgp-macro-lib/src/derive_getter/with_provider.rs @@ -60,7 +60,7 @@ pub fn derive_with_provider_impl( })?); } - let provider_constraint = if field.field_mut.is_none() { + let provider_constraint = if field.receiver_mut.is_none() { if let FieldMode::Slice = field.field_mode { quote! { FieldGetter< #receiver_type, #component_type, Value: AsRef< [ #field_type ] > + 'static > From 29fd7be900a774a146923012fd291b51390e7123 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Wed, 18 Feb 2026 10:56:42 +0100 Subject: [PATCH 3/5] Disallow mutable implicit variable --- crates/cgp-macro-lib/Cargo.toml | 2 +- .../src/cgp_fn/parse_implicits.rs | 31 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/crates/cgp-macro-lib/Cargo.toml b/crates/cgp-macro-lib/Cargo.toml index 4e800f2a..a50c39ad 100644 --- a/crates/cgp-macro-lib/Cargo.toml +++ b/crates/cgp-macro-lib/Cargo.toml @@ -15,7 +15,7 @@ description = """ default = [] [dependencies] -syn = { version = "2.0.95", features = [ "full", "extra-traits" ] } +syn = { version = "2.0.95", features = [ "full", "extra-traits", "visit" ] } quote = "1.0.38" proc-macro2 = "1.0.92" prettyplease = "0.2.27" diff --git a/crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs b/crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs index 37bb8748..199b5c23 100644 --- a/crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs +++ b/crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs @@ -2,7 +2,8 @@ use std::mem; use syn::punctuated::Punctuated; use syn::token::Comma; -use syn::{Attribute, FnArg, Meta, Pat, PatType, Receiver}; +use syn::visit::{self, Visit}; +use syn::{Attribute, FnArg, Meta, Pat, PatIdent, PatType, Receiver}; use crate::cgp_fn::ImplicitArgField; use crate::derive_getter::parse_field_type; @@ -35,7 +36,15 @@ pub fn parse_implicit_arg(receiver: &Receiver, arg: &PatType) -> syn::Result bool { _ => false, } } + +pub fn has_mut_pattern(pat: &Pat) -> bool { + let mut checker = MutChecker { has_mut: false }; + checker.visit_pat(pat); + checker.has_mut +} + +struct MutChecker { + has_mut: bool, +} + +impl<'ast> Visit<'ast> for MutChecker { + fn visit_pat_ident(&mut self, node: &'ast PatIdent) { + if node.mutability.is_some() { + self.has_mut = true; + } + // Continue walking through the rest of the pattern + visit::visit_pat_ident(self, node); + } +} From 1ad441ac793300440c327c54f22c9b8cdc6bc6d5 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Wed, 18 Feb 2026 11:21:54 +0100 Subject: [PATCH 4/5] Add multi-args test --- crates/cgp-macro-lib/src/cgp_fn/constraint.rs | 24 --------------- crates/cgp-macro-lib/src/cgp_fn/mod.rs | 1 - crates/cgp-tests/tests/cgp_fn_tests/mod.rs | 1 + crates/cgp-tests/tests/cgp_fn_tests/multi.rs | 30 +++++++++++++++++++ 4 files changed, 31 insertions(+), 25 deletions(-) delete mode 100644 crates/cgp-macro-lib/src/cgp_fn/constraint.rs create mode 100644 crates/cgp-tests/tests/cgp_fn_tests/multi.rs diff --git a/crates/cgp-macro-lib/src/cgp_fn/constraint.rs b/crates/cgp-macro-lib/src/cgp_fn/constraint.rs deleted file mode 100644 index 77193b55..00000000 --- a/crates/cgp-macro-lib/src/cgp_fn/constraint.rs +++ /dev/null @@ -1,24 +0,0 @@ -// pub fn derive_implicit_arg_constraint( -// field: &ImplicitArgField, -// ) -> syn::Result { -// let field_symbol = &field.field_name; -// let field_type = &field.field_type; - -// let constraint = if field.field_mut.is_none() { -// if let FieldMode::Slice = field.field_mode { -// quote! { -// HasField< #field_symbol, Value: AsRef< [ #field_type ] > + 'static > -// } -// } else { -// quote! { -// HasField< #field_symbol, Value = #field_type > -// } -// } -// } else { -// quote! { -// HasFieldMut< #field_symbol, Value = #field_type > -// } -// }; - -// parse2(constraint) -// } diff --git a/crates/cgp-macro-lib/src/cgp_fn/mod.rs b/crates/cgp-macro-lib/src/cgp_fn/mod.rs index 83025a80..3c094c21 100644 --- a/crates/cgp-macro-lib/src/cgp_fn/mod.rs +++ b/crates/cgp-macro-lib/src/cgp_fn/mod.rs @@ -1,5 +1,4 @@ mod attributes; -mod constraint; mod derive; mod fn_body; mod item_impl; diff --git a/crates/cgp-tests/tests/cgp_fn_tests/mod.rs b/crates/cgp-tests/tests/cgp_fn_tests/mod.rs index 8f756f0c..90833d71 100644 --- a/crates/cgp-tests/tests/cgp_fn_tests/mod.rs +++ b/crates/cgp-tests/tests/cgp_fn_tests/mod.rs @@ -2,6 +2,7 @@ pub mod basic; pub mod call; pub mod extend; pub mod generics; +pub mod multi; pub mod mutable; pub mod use_type; pub mod use_type_alias; diff --git a/crates/cgp-tests/tests/cgp_fn_tests/multi.rs b/crates/cgp-tests/tests/cgp_fn_tests/multi.rs new file mode 100644 index 00000000..758186c5 --- /dev/null +++ b/crates/cgp-tests/tests/cgp_fn_tests/multi.rs @@ -0,0 +1,30 @@ +use core::fmt::Display; + +use cgp::prelude::*; + +pub trait HasFooType { + type Foo; +} + +pub trait HasBarType { + type Bar; + + type Baz; +} + +#[allow(unused)] +#[cgp_fn] +#[use_type(>::{Foo as FooX}, >::{Foo as FooY}, HasBarType::{Bar, Baz})] +pub fn do_foo_bar( + &self, + x: X, + #[implicit] foo_x: &FooX, + #[implicit] foo_y: &FooY, + #[implicit] bar: &Bar, + y: Y, +) -> Option +where + FooX: Display, +{ + None +} From 60b409273685486dfcac92b36b1080e935393b07 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Wed, 18 Feb 2026 11:33:17 +0100 Subject: [PATCH 5/5] Explicitly annotate implicit variable types --- crates/cgp-macro-lib/src/cgp_fn/fn_body.rs | 3 ++- crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs | 5 +++-- crates/cgp-macro-lib/src/cgp_fn/spec.rs | 1 + crates/cgp-macro-lib/src/cgp_fn/substitute_type.rs | 12 ++++++++++-- crates/cgp-tests/tests/cgp_fn_tests/use_type.rs | 3 ++- .../cgp-tests/tests/cgp_fn_tests/use_type_alias.rs | 3 ++- 6 files changed, 20 insertions(+), 7 deletions(-) diff --git a/crates/cgp-macro-lib/src/cgp_fn/fn_body.rs b/crates/cgp-macro-lib/src/cgp_fn/fn_body.rs index bd6a4675..f4919e74 100644 --- a/crates/cgp-macro-lib/src/cgp_fn/fn_body.rs +++ b/crates/cgp-macro-lib/src/cgp_fn/fn_body.rs @@ -14,6 +14,7 @@ pub fn inject_implicit_args(args: &[ImplicitArgField], body: &mut Block) -> syn: pub fn inject_implicit_arg(arg: &ImplicitArgField, body: &mut Block) -> syn::Result<()> { let field_name = &arg.field_name; + let arg_type = &arg.arg_type; let field_symbol = symbol_from_string(&field_name.to_string()); @@ -30,7 +31,7 @@ pub fn inject_implicit_arg(arg: &ImplicitArgField, body: &mut Block) -> syn::Res let call_expr = extend_call_expr(call_expr, &arg.field_mode, &arg.field_mut); let statement = parse2(quote! { - let #field_name = #call_expr; + let #field_name: #arg_type = #call_expr; })?; body.stmts.insert(0, statement); diff --git a/crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs b/crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs index 199b5c23..dbcd6253 100644 --- a/crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs +++ b/crates/cgp-macro-lib/src/cgp_fn/parse_implicits.rs @@ -43,17 +43,18 @@ pub fn parse_implicit_arg(receiver: &Receiver, arg: &PatType) -> syn::Result, pub field_mode: FieldMode, + pub arg_type: Type, } #[derive(Default)] diff --git a/crates/cgp-macro-lib/src/cgp_fn/substitute_type.rs b/crates/cgp-macro-lib/src/cgp_fn/substitute_type.rs index 4ed75a72..dbcd2d0c 100644 --- a/crates/cgp-macro-lib/src/cgp_fn/substitute_type.rs +++ b/crates/cgp-macro-lib/src/cgp_fn/substitute_type.rs @@ -10,6 +10,7 @@ pub fn substitute_abstract_type( ) -> TokenStream { let mut out = TokenStream::new(); let mut last_token_was_colon = false; + let mut last_two_tokens_was_colon = false; for token_tree in body.into_iter() { let token_is_colon = if let TokenTree::Punct(punct) = &token_tree @@ -29,7 +30,7 @@ pub fn substitute_abstract_type( let mut replaced_ident = false; for type_spec in type_specs { - if !last_token_was_colon + if !last_two_tokens_was_colon && let Some(replacement_ident) = type_spec.replace_ident(&ident) { let trait_path = &type_spec.trait_path; @@ -53,7 +54,14 @@ pub fn substitute_abstract_type( } } - last_token_was_colon = token_is_colon; + if token_is_colon { + if last_token_was_colon { + last_token_was_colon = true; + } else { + last_token_was_colon = true; + last_two_tokens_was_colon = false; + } + } } out diff --git a/crates/cgp-tests/tests/cgp_fn_tests/use_type.rs b/crates/cgp-tests/tests/cgp_fn_tests/use_type.rs index 3340bdae..662a8039 100644 --- a/crates/cgp-tests/tests/cgp_fn_tests/use_type.rs +++ b/crates/cgp-tests/tests/cgp_fn_tests/use_type.rs @@ -13,5 +13,6 @@ pub fn rectangle_area(&self, #[implicit] width: Scalar, #[implicit] height: Scal where Scalar: Mul + Clone, { - width * height + let res: Scalar = width * height; + res } diff --git a/crates/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs b/crates/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs index b6748a16..ac48070f 100644 --- a/crates/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs +++ b/crates/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs @@ -13,5 +13,6 @@ pub fn rectangle_area(&self, #[implicit] width: S, #[implicit] height: S) -> S where S: Mul + Clone, { - width * height + let res: S = width * height; + res }