dtolnay / linkme

Safe cross-platform linker shenanigans

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Recognize distributed_slice on functions as a special case

dtolnay opened this issue · comments

Building registries of function pointers is probably the most common use case for distributed_slice.

The benchmark harness use case in the readme is one example, or the following registry of error type conversions for crates to register semantically meaningful conversions into Python errors for their custom error types.

use cpython::{exc, PyErr, Python};
use distributed_slice::distributed_slice;
use std::io;

#[distributed_slice]
pub static INTO_PYERR: [fn(&anyhow::Error, py: Python<'_>) -> Option<PyErr>] = [..];

#[distributed_slice(INTO_PYERR)]
static IO_INTO_PYERR: fn(&anyhow::Error, py: Python<'_>) -> Option<PyErr> = io_into_pyerr;

fn io_into_pyerr(err: &anyhow::Error, py: Python<'_>) -> Option<PyErr> {
    let err = err.downcast_ref::<io::Error>()?;
    Some(PyErr::new::<exc::IOError, _>(
        py,
        (e.raw_os_error(), e.to_string()),
    ))
}

It would be great to handle function pointers as a special case in our attribute macro to allow this more concise invocation:

#[distributed_slice(INTO_PYERR)]
fn io_into_pyerr(err: &anyhow::Error, py: Python<'_>) -> Option<PyErr> {
    ...
}

which would expand to the pair of IO_INTO_PYERR static + io_into_pyerr function as above.