Skip to content

Support matching interpolated types in macro invocation syntax #6659

Closed
@zargony

Description

@zargony

It would be nice if macros could be invoked using an interpolated type from a transcription of another macro.

This is my macro to convert C typed values from an external library to Rust types:

macro_rules! c_to_rust(
  ($v:ident c_int) => ($v);
  ($v:ident *c_char) => (str::raw::from_c_str($v));
)

It works fine when invoked like c_to_rust!(i: c_int), but it can't be used from within another macro using an interpolated type like c_to_rust!($v: $ty) (where the macro's invocation contains $v:ident, $ty:ty) - probably because interpolated types cannot be matched literally in the invocation syntax.

Here's my other macro which fails to use the above one. For bindings to an external library, I need to provide a lot of callback functions. So I'm using a macro to define them, since they only differ in name and parameter types. But I want the forwarding function to convert the parameter to Rust types before passing them along, which unfortunately doesn't work. (Any hints on how to work around this are welcome, I didn't find a suitable way without repeating a lot of code)

macro_rules! forward_callback(
  ($fn_name:ident, $op_name:ident, $($param_name:ident: $param_type:ty),*) => (
    extern fn $fn_name (userdata: *c_void, $($param_name: $param_type),*) {
      unsafe {
        let session: &Session = cast::transmute(userdata);
        session.$op_name($(c_to_rust!($param_name: $param_type)),*);
                                                    ^~~~~~~~~ FAILS
      }
    }
  );
)

// Intended use:
forward_callback!(function1, p1: c_int)
forward_callback!(function2, p1: c_int, p2: *c_char)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-syntaxextArea: Syntax extensions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions