How to import types defined in a function

I have a derive macro, which generates codes from a given type:

#[derive(FooMacro)]
struct Foo{}

and it will change to

    struct Foo {}

    mod private {
        use super::Foo;
        struct Bar {
            i: Foo,
        }
    }
    pub use private::*;

but I never expected somebody to use like this:

fn main() {
    struct Foo {}

    mod private {
        use super::Foo;
        struct Bar {
            i: Foo,
        }
    }
    pub use private::*;
}

In this case, the struct is defined in a function, I cannot import type Foo into my private mod, how can I deal with this problem?

1 Like

Not currently possible. See this issue.

1 Like

A possible workaround could be to use a trait:

fn main() {
    struct Foo {}

    impl private::__NameType for () {
        type Type = Foo;
    }
    mod private {
        pub(super) trait __NameType {
            type Type;
        }
        struct Bar {
            i: <() as __NameType>::Type,
        }
    }
    pub use private::*;
}
4 Likes

Initially when I read this thread, I felt a bit confused because I could've sworn I have done something like this without similar issues. However, looking at my own projects I realize I was using another, more limited technique:

Basically, for macros whose only "public" output are impls, there is an easier way to encapsulate private items defined by a macro: All you have to do is expand to an unnamed const.

const _: () = {
    impl Trait for Struct {
        fn method(&self) -> Struct { ... } 
    }
    // other private items can be defined here
};

But of course, with regards to the problem in the OP, this line is the killer:

So I only bring this up as a related technique, and not a solution to the problem.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.