Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closures accepting structs with lifetimes #69

Open
Michael-F-Bryan opened this issue Jun 28, 2021 · 2 comments
Open

Closures accepting structs with lifetimes #69

Michael-F-Bryan opened this issue Jun 28, 2021 · 2 comments
Assignees
Labels
K-feature Kind: proposed new code to implement new behaviour

Comments

@Michael-F-Bryan
Copy link

I ran into an annoying issue with BoxDynFnMut1 and friends when you try to pass around a struct with a non-'static lifetime due to the lack of higher-kinded types.

Basically, I want to let users set their own logging function. In normal Rust you'd write something like this:

pub fn set_logger(log_func: Box<dyn Fn(&log::Record<'_>)>) { ... }

The equivalent using safer_ffi would be (in theory) something like this:

#[ffi_export]
pub fn set_logger(log_func: for<'a> BoxDynFnMut1<(), LogRecord<'a>>) { ... }

#[derive_ReprC]
#[repr(C)]
pub struct LogRecord<'a> {
    level: LogLevel,
    target: str_ref<'a>,
}

Obviously for<'a> SomeStruct isn't valid syntax and you get an "Error: expected trait, found struct BoxDynFnMut1" error, however without the for<'a> you get "Error: cannot infer an appropriate lifetime due to conflicting requirements" when you try to use it in practice.

This is a concrete example of the "improve support for closures" mentioned in #47.

@danielhenrymantilla
Copy link
Collaborator

danielhenrymantilla commented Jun 28, 2021

Indeed! FWIW, there is already support for higher-ranked function pointers (stateless), which can test with the ditto internal branch:

#[derive_ReprC] // Both these attrs will likely become `#[safer_ffi::repr(transparent)]`
#[repr(transparent)]
struct MyLoggerFnPointer(
    extern "C" fn(&log::Record<'_>),
);

One API for higher-ranked closures, right now, would be an API very similar to https://docs.rs/stackbox/0.1.2/stackbox/macro.custom_dyn.html (or at least that would be the general solution to #47):

#[safer_ffi::repr(C)] // Defines `BoxDynMyLogger<'_>`, `ArcDynMyLogger<'_>` types.
trait MyLogger : Send + Sync {
    fn call (self: &'_ Self, _: &log::Record<'_>);
}
  • Btw @Michael-F-Bryan, thanks to your blogpost, there may even be a #[safer_ffi::repr(C, thin)] option 🙃

If you have suggestions ideas for these things, I'm all ears 🙂

For the specific case of closures, I could also imagine using the same #[repr(transparent)] syntax showcased above, but directly supporting the repr_c::closure::… types:

#[derive_ReprC]
#[repr(transparent)]
struct MyLoggerClosure (
    repr_c::BoxDynClosure<fn(&log::Record<'_>)>, // <- optional future syntax for the closure types
);

@danielhenrymantilla danielhenrymantilla self-assigned this Jun 28, 2021
@danielhenrymantilla danielhenrymantilla added K-feature Kind: proposed new code to implement new behaviour soon-ish labels Jun 28, 2021
@steph-lui steph-lui added 2022-Q2 and removed 2022-Q1 labels Apr 4, 2022
@steph-lui steph-lui removed the 2022-Q2 label Jul 14, 2022
@danielhenrymantilla
Copy link
Collaborator

danielhenrymantilla commented Sep 11, 2023

I know this is an old issue, but I wanted to gauge the situation at the moment, @Michael-F-Bryan:

  • safer-ffi nowadays supports FFI-safe dyn traits which can be Boxed, and which hopefully do support this generic lifetime param in input;
  • thanks to https://docs.rs/higher-kinded-types, it would be possible to express some ForFn<ForLt!(&log::Record<'_>)> kind of type, at least in the covariant case
    • (or ForFn<For!(<'a, 'b> = &'a log::Record<'b>)> in the invariant case)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
K-feature Kind: proposed new code to implement new behaviour
Projects
None yet
Development

No branches or pull requests

3 participants