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

module submit doesn't work when coming from macro #35

Closed
mimoo opened this issue Sep 14, 2021 · 2 comments
Closed

module submit doesn't work when coming from macro #35

mimoo opened this issue Sep 14, 2021 · 2 comments

Comments

@mimoo
Copy link

mimoo commented Sep 14, 2021

Hey! I've been setting up the inventory stuff via a macro from another crate:

#[proc_macro]
pub fn init_gen(_item: TokenStream) -> TokenStream {
    r#"
    use ::ocaml::inventory;

    pub struct OcamlFunc {
        pub module: &'static str,
        pub name: &'static str,
        pub args: Vec<&'static str>,
    }
    
    impl OcamlFunc {
        pub fn new(module: &'static str, name: &'static str, args: Vec<&'static str>) -> Self {
            OcamlFunc { module, name, args }
        }
    }

    pub fn gen_ocaml_bindings() {
        // group by module

        // generate .ml code
        for flag in inventory::iter::<OcamlFunc> {
            println!("module {} = struct external {}: unit -> string = \"{}\" end", flag.module, flag.name, flag.name);
        }
    }
    
// this works
    inventory::submit! {
        OcamlFunc::new("init", "test init", vec!["t: int"])
    }

    // this doesn't work v
    pub mod inside_mod {
        use super::*;
        inventory::submit! {
            OcamlFunc::new("init2", "test init inside mod", vec!["t: int"])
        }

    }

    inventory::collect!(OcamlFunc);
    "#
    .parse()
    .unwrap()
}

and it seems to work except when I try to submit from inside another module. Here's the code from the proc macro crate, but doing it from inside another module where I call

ocaml::init_gen!();

// this works
inventory::submit! {
    OcamlFunc::new("init3", "test init inside mod", vec!["t: int"])
}

pub mod a {
    use super::*;

// this doesn't work
    inventory::submit! {
        OcamlFunc::new("init4", "test init inside mod", vec!["t: int"])
    }
}
@mimoo
Copy link
Author

mimoo commented Sep 14, 2021

This is really troubling me. This is an expanded example that works:

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2018::*;
#[macro_use]
extern crate std;
pub struct Flag {
    short: char,
    name: &'static str,
    /* ... */
}

impl Flag {
    pub fn new(short: char, name: &'static str) -> Self { Flag{short, name,} }
}





#[allow(non_upper_case_globals)]
extern fn __init12616011980604515118() {
    inventory::submit({ Flag::new('v', "verbose") });
}
#[used]
#[allow(non_upper_case_globals)]
#[doc(hidden)]
#[link_section = "__DATA,__mod_init_func"]
static __init12616011980604515118___rust_ctor___ctor: unsafe extern "C" fn() =
    {
        unsafe extern "C" fn __init12616011980604515118___rust_ctor___ctor() {
            __init12616011980604515118()
        }
        ;
        __init12616011980604515118___rust_ctor___ctor
    };
mod a {
    use super::Flag;
    #[allow(non_upper_case_globals)]
    extern fn __init3632956075760860679() {
        inventory::submit({ Flag::new('l', "loose") });
    }
    #[used]
    #[allow(non_upper_case_globals)]
    #[doc(hidden)]
    #[link_section = "__DATA,__mod_init_func"]
    static __init3632956075760860679___rust_ctor___ctor:
     unsafe extern "C" fn() =
        {
            unsafe extern "C" fn __init3632956075760860679___rust_ctor___ctor() {
                __init3632956075760860679()
            }
            ;
            __init3632956075760860679___rust_ctor___ctor
        };
}
impl ::inventory::Collect for Flag {
    #[inline]
    fn registry() -> &'static ::inventory::Registry<Self> {
        static REGISTRY: ::inventory::Registry<Flag> =
            ::inventory::Registry::new();
        &REGISTRY
    }
}
fn main() {
    for flag in inventory::iter::<Flag> {
        {
            ::std::io::_print(match match (&flag.short, &flag.name) {
                                        (arg0, arg1) =>
                                        [::core::fmt::ArgumentV1::new(arg0,
                                                                      ::core::fmt::Display::fmt),
                                         ::core::fmt::ArgumentV1::new(arg1,
                                                                      ::core::fmt::Display::fmt)],
                                    } {
                                  ref args => unsafe {
                                      ::core::fmt::Arguments::new_v1(&["-",
                                                                       ", --",
                                                                       "\n"],
                                                                     args)
                                  }
                              });
        };
    }
}

and this is my expanded example that doesn't work:

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2018::*;
#[macro_use]
extern crate std;
use ::ocaml::inventory;
pub struct OcamlFunc {
    pub module: &'static str,
    pub name: &'static str,
    pub args: Vec<&'static str>,
}
impl OcamlFunc {
    pub fn new(module: &'static str, name: &'static str,
               args: Vec<&'static str>) -> Self {
        OcamlFunc{module, name, args,}
    }
}
pub fn gen_ocaml_bindings() {
    for flag in inventory::iter::<OcamlFunc> {

        /*
        #[ocaml::func]
        pub fn hello_world() -> &'static str {
            "hello, world!"
        }

        #[ocaml::func]
        pub fn second_one() -> &'static str {
            "hello, world!"
        }
        */



        /*
        #[ocaml::func]
        pub fn third_one() {}
        */

        {
            ::std::io::_print(match match (&flag.module, &flag.name,
                                           &flag.name) {
                                        (arg0, arg1, arg2) =>
                                        [::core::fmt::ArgumentV1::new(arg0,
                                                                      ::core::fmt::Display::fmt),
                                         ::core::fmt::ArgumentV1::new(arg1,
                                                                      ::core::fmt::Display::fmt),
                                         ::core::fmt::ArgumentV1::new(arg2,
                                                                      ::core::fmt::Display::fmt)],
                                    } {
                                  ref args => unsafe {
                                      ::core::fmt::Arguments::new_v1(&["module ",
                                                                       " = struct external ",
                                                                       ": unit -> string = \"",
                                                                       "\" end\n"],
                                                                     args)
                                  }
                              });
        };
    }
}
#[allow(non_upper_case_globals)]
extern fn __init7240165574856463891() {
    inventory::submit({
                          OcamlFunc::new("init", "test init",
                                         <[_]>::into_vec(box ["t: int"]))
                      });
}
#[used]
#[allow(non_upper_case_globals)]
#[doc(hidden)]
#[link_section = "__DATA,__mod_init_func"]
static __init7240165574856463891___rust_ctor___ctor: unsafe extern "C" fn() =
    {
        unsafe extern "C" fn __init7240165574856463891___rust_ctor___ctor() {
            __init7240165574856463891()
        }
        ;
        __init7240165574856463891___rust_ctor___ctor
    };
pub mod inside_mod {
    use super::*;
    #[allow(non_upper_case_globals)]
    extern fn __init16324153154278459067() {
        inventory::submit({
                              OcamlFunc::new("init2", "test init inside mod",
                                             <[_]>::into_vec(box ["t: int"]))
                          });
    }
    #[used]
    #[allow(non_upper_case_globals)]
    #[doc(hidden)]
    #[link_section = "__DATA,__mod_init_func"]
    static __init16324153154278459067___rust_ctor___ctor:
     unsafe extern "C" fn() =
        {
            unsafe extern "C" fn __init16324153154278459067___rust_ctor___ctor() {
                __init16324153154278459067()
            }
            ;
            __init16324153154278459067___rust_ctor___ctor
        };
}
impl ::inventory::Collect for OcamlFunc {
    #[inline]
    fn registry() -> &'static ::inventory::Registry<Self> {
        static REGISTRY: ::inventory::Registry<OcamlFunc> =
            ::inventory::Registry::new();
        &REGISTRY
    }
}
#[allow(non_upper_case_globals)]
extern fn __init9752370030967368522() {
    inventory::submit({
                          OcamlFunc::new("init3", "test init inside mod",
                                         <[_]>::into_vec(box ["t: int"]))
                      });
}
#[used]
#[allow(non_upper_case_globals)]
#[doc(hidden)]
#[link_section = "__DATA,__mod_init_func"]
static __init9752370030967368522___rust_ctor___ctor: unsafe extern "C" fn() =
    {
        unsafe extern "C" fn __init9752370030967368522___rust_ctor___ctor() {
            __init9752370030967368522()
        }
        ;
        __init9752370030967368522___rust_ctor___ctor
    };
pub mod a {
    use super::*;
    #[allow(non_upper_case_globals)]
    extern fn __init7342976490476293494() {
        inventory::submit({
                              OcamlFunc::new("init4", "test init inside mod",
                                             <[_]>::into_vec(box ["t: int"]))
                          });
    }
    #[used]
    #[allow(non_upper_case_globals)]
    #[doc(hidden)]
    #[link_section = "__DATA,__mod_init_func"]
    static __init7342976490476293494___rust_ctor___ctor:
     unsafe extern "C" fn() =
        {
            unsafe extern "C" fn __init7342976490476293494___rust_ctor___ctor() {
                __init7342976490476293494()
            }
            ;
            __init7342976490476293494___rust_ctor___ctor
        };
}

@dtolnay
Copy link
Owner

dtolnay commented Nov 10, 2021

seems to work except when I try to submit from inside another module

I believe this is a duplicate of #9.

@dtolnay dtolnay closed this as completed Nov 10, 2021
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

No branches or pull requests

2 participants