Skip to content

Fix #107: support generic functions with reference type parameters in func!#120

Open
mazong1123 wants to merge 1 commit intomainfrom
fix/issue-107-generic-func-lifetime
Open

Fix #107: support generic functions with reference type parameters in func!#120
mazong1123 wants to merge 1 commit intomainfrom
fix/issue-107-generic-func-lifetime

Conversation

@mazong1123
Copy link
Collaborator

Summary

Fixes #107 by removing the type coercion in func! macro's Case 1 and Case 2, which fails for generic functions whose type parameters are reference types.

Problem

When mocking a generic function like nix::unistd::execvp<S: AsRef<CStr>>, the user specifies:

func!(nix::unistd::execvp, fn(&CStr, &[&CStr]) -> Result<...>)

The explicit fn pointer type fn(&CStr, &[&CStr]) desugars to for<'a, 'b, 'c> fn(&'a CStr, &'b [&'c CStr]) (3 independent lifetimes). But the monomorphized execvp::<&CStr> has for<'a, 'b> fn(&'a CStr, &'b [&CStr]) (2 lifetimes — the inner reference's lifetime is tied to the generic parameter). Rust's type system rejects this coercion.

Fix

Replace the type coercion (let fn_val: $fn_type = $f) with a direct cast to *const () and use type_name::<$fn_type>() for the signature string. This:

  • Avoids the lifetime coercion entirely
  • Produces identical signature strings (both are fn pointer type names)
  • Preserves TypeId-based type safety checking
  • Is fully backward compatible — all 132 tests pass

For generic functions with reference type params, users provide turbofish:

func!(execvp::<&CStr>, fn(&CStr, &[&CStr]) -> Result<...>)

Testing

Closes #107

… func!

Remove type coercion in func! Case 1 and Case 2. Instead of
coercing the function expression to the user-specified fn pointer type
(which fails when a generic type parameter is a reference due to
Rust's higher-ranked lifetime mismatch), cast the function item
directly to *const () and use type_name::<fn_type>() for the
signature string.

For generic functions like execvp<S: AsRef<CStr>>, users can now
use turbofish to monomorphize:
  func!(execvp::<&CStr>, fn(&CStr, &[&CStr]) -> Result<...>)

This is non-breaking: all existing tests pass unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

func! macro lifetime mismatch for generic functions

1 participant