From 62f7e551fc125f2d73a34b1943def92e416feda8 Mon Sep 17 00:00:00 2001 From: Ajay Singh Date: Sat, 25 Jul 2026 19:12:29 +0530 Subject: [PATCH 1/2] Add return value support to overload! macro --- .github/workflows/check.yml | 6 ++++ .../src/bin/return-values-complex.rs | 35 +++++++++++++++++++ .../src/bin/return-values-mixed-args.rs | 21 +++++++++++ .../src/bin/return-values-mixed-unit.rs | 19 ++++++++++ .../src/bin/return-values-non-copy.rs | 21 +++++++++++ .../src/bin/return-values-zero-args.rs | 21 +++++++++++ splat-overload-test/src/bin/return-values.rs | 21 +++++++++++ splat-overload/src/lib.rs | 23 +++++++++--- 8 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 splat-overload-test/src/bin/return-values-complex.rs create mode 100644 splat-overload-test/src/bin/return-values-mixed-args.rs create mode 100644 splat-overload-test/src/bin/return-values-mixed-unit.rs create mode 100644 splat-overload-test/src/bin/return-values-non-copy.rs create mode 100644 splat-overload-test/src/bin/return-values-zero-args.rs create mode 100644 splat-overload-test/src/bin/return-values.rs diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index ae437e0..ac34af2 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -54,6 +54,12 @@ jobs: run: | cargo run --all-features --bin multiple-args cargo run --all-features --bin multiple-mixed-args + cargo run --all-features --bin return-values + cargo run --all-features --bin return-values-mixed-args + cargo run --all-features --bin return-values-mixed-unit + cargo run --all-features --bin return-values-complex + cargo run --all-features --bin return-values-non-copy + cargo run --all-features --bin return-values-zero-args clippy-rust: name: 4. Clippy lints on Rust crates diff --git a/splat-overload-test/src/bin/return-values-complex.rs b/splat-overload-test/src/bin/return-values-complex.rs new file mode 100644 index 0000000..f329bee --- /dev/null +++ b/splat-overload-test/src/bin/return-values-complex.rs @@ -0,0 +1,35 @@ +#![feature(splat)] +#![feature(tuple_trait)] +#![allow(incomplete_features)] +#![allow(unused_braces)] + +use splat_overload::overload; + +overload! { + fn foo(x: i32) -> i32 { + if x < 0 { + return 0; + } + x * 2 + } + fn foo(x: i32, y: i32) -> Vec { vec![x, y] } + fn foo(x: i32, y: i32, z: i32) -> String { format!("{}-{}-{}", x, y, z) } +} + +fn main() { + let a = foo(-5); + assert_eq!(a, 0); + println!("early return result: {}", a); + + let b = foo(10); + assert_eq!(b, 20); + println!("normal path result: {}", b); + + let c = foo(1i32, 2); + assert_eq!(c, vec![1, 2]); + println!("vec result: {:?}", c); + + let d = foo(1i32, 2, 3); + assert_eq!(d, "1-2-3"); + println!("string result: {}", d); +} diff --git a/splat-overload-test/src/bin/return-values-mixed-args.rs b/splat-overload-test/src/bin/return-values-mixed-args.rs new file mode 100644 index 0000000..14f1e15 --- /dev/null +++ b/splat-overload-test/src/bin/return-values-mixed-args.rs @@ -0,0 +1,21 @@ +#![feature(splat)] +#![feature(tuple_trait)] +#![allow(incomplete_features)] +#![allow(unused_braces)] + +use splat_overload::overload; + +overload! { + fn foo(x: f64, y: i32) -> i32 { (x as i32) + y } + fn foo(x: i32) -> i32 { x * 2 } +} + +fn main() { + let a = foo(3.7, 10); + assert_eq!(a, 13); + println!("mixed args result: {}", a); + + let b = foo(21); + assert_eq!(b, 42); + println!("single arg result: {}", b); +} diff --git a/splat-overload-test/src/bin/return-values-mixed-unit.rs b/splat-overload-test/src/bin/return-values-mixed-unit.rs new file mode 100644 index 0000000..b4b6d49 --- /dev/null +++ b/splat-overload-test/src/bin/return-values-mixed-unit.rs @@ -0,0 +1,19 @@ +#![feature(splat)] +#![feature(tuple_trait)] +#![allow(incomplete_features)] +#![allow(unused_braces)] + +use splat_overload::overload; + +overload! { + fn foo(x: i32) -> i32 { x * 2 } + fn foo(x: f64) { println!("f64: {}", x); } +} + +fn main() { + let a = foo(21); + assert_eq!(a, 42); + println!("i32 result: {}", a); + foo(2.5); + println!("f64 call completed"); +} diff --git a/splat-overload-test/src/bin/return-values-non-copy.rs b/splat-overload-test/src/bin/return-values-non-copy.rs new file mode 100644 index 0000000..7f02be3 --- /dev/null +++ b/splat-overload-test/src/bin/return-values-non-copy.rs @@ -0,0 +1,21 @@ +#![feature(splat)] +#![feature(tuple_trait)] +#![allow(incomplete_features)] +#![allow(unused_braces)] + +use splat_overload::overload; + +overload! { + fn foo(x: String) -> String { x } + fn foo(x: String, y: String) -> String { format!("{}{}", x, y) } +} + +fn main() { + let a = foo("We love Rust!".to_string()); + assert_eq!(a, "We love Rust!"); + println!("single string result: {}", a); + + let b = foo("We love ".to_string(), "Rust!".to_string()); + assert_eq!(b, "We love Rust!"); + println!("concatenated result: {}", b); +} diff --git a/splat-overload-test/src/bin/return-values-zero-args.rs b/splat-overload-test/src/bin/return-values-zero-args.rs new file mode 100644 index 0000000..811d6ab --- /dev/null +++ b/splat-overload-test/src/bin/return-values-zero-args.rs @@ -0,0 +1,21 @@ +#![feature(splat)] +#![feature(tuple_trait)] +#![allow(incomplete_features)] +#![allow(unused_braces)] + +use splat_overload::overload; + +overload! { + fn foo() -> i32 { 42 } + fn foo(x: i32) -> i32 { x } +} + +fn main() { + let a = foo(); + assert_eq!(a, 42); + println!("zero args result: {}", a); + + let b = foo(10i32); + assert_eq!(b, 10); + println!("one arg result: {}", b); +} diff --git a/splat-overload-test/src/bin/return-values.rs b/splat-overload-test/src/bin/return-values.rs new file mode 100644 index 0000000..e44b35b --- /dev/null +++ b/splat-overload-test/src/bin/return-values.rs @@ -0,0 +1,21 @@ +#![feature(splat)] +#![feature(tuple_trait)] +#![allow(incomplete_features)] +#![allow(unused_braces)] + +use splat_overload::overload; + +overload! { + fn foo(x: i32) -> i32 { x * 2 } + fn foo(x: f64) -> f64 { x * 2.0 } +} + +fn main() { + let a = foo(21); + assert_eq!(a, 42); + println!("i32 result: {}", a); + + let b = foo(1.5); + assert_eq!(b, 3.0); + println!("f64 result: {}", b); +} diff --git a/splat-overload/src/lib.rs b/splat-overload/src/lib.rs index 2e955ab..fc7601b 100644 --- a/splat-overload/src/lib.rs +++ b/splat-overload/src/lib.rs @@ -64,9 +64,23 @@ pub fn overload(input: TokenStream) -> TokenStream { arg_indices.push(quote! { self.#index }); } } + + let output_ty = match &func.sig.output { + syn::ReturnType::Default => quote! { () }, + syn::ReturnType::Type(_, ty) => quote! { #ty }, + }; + + //Check if the argument is zero + let tuple_ty = if arg_types.is_empty() { + quote! { () } + } else { + quote! { (#(#arg_types),*,) } + }; + impls.push(quote! { - impl #trait_name for (#(#arg_types),*,) { - fn call(self) { + impl #trait_name for #tuple_ty { + type Output = #output_ty; + fn call(self) -> Self::Output{ #(let #arg_names = #arg_indices;)* #block } @@ -75,12 +89,13 @@ pub fn overload(input: TokenStream) -> TokenStream { } let generated = quote! { trait #trait_name: std::marker::Tuple { - fn call(self); + type Output; + fn call(self) -> Self::Output; } #(#impls)* - fn #fn_name(#[splat] args: T) { + fn #fn_name(#[splat] args: T) -> T::Output{ args.call() } }; From ed73cde8efd3bde343cac8a386a46c7e16bd14e0 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 27 Jul 2026 16:50:32 +1000 Subject: [PATCH 2/2] Fix comment wording in splat-overload/src/lib.rs --- splat-overload/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splat-overload/src/lib.rs b/splat-overload/src/lib.rs index fc7601b..68e3a34 100644 --- a/splat-overload/src/lib.rs +++ b/splat-overload/src/lib.rs @@ -70,7 +70,7 @@ pub fn overload(input: TokenStream) -> TokenStream { syn::ReturnType::Type(_, ty) => quote! { #ty }, }; - //Check if the argument is zero + // Check if there are no arguments let tuple_ty = if arg_types.is_empty() { quote! { () } } else {