Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to `use` function scoped structs?

Tags:

rust

Consider the following contrived example:

mod Parent {
    fn my_fn() {
        struct MyStruct;

        mod Inner {
            use super::MyStruct; //Error: unresolved import `super::MyStruct`. No `MyStruct` in `Parent`
        }
    }
}

How can I import MyStruct here from the inner module?


Motivation

While the above is code that you'll never write manually, it is code that is useful to generate. A real-world use-case would be a derive-macro. Let's say I want this:

#[derive(Derivative)]
struct MyStruct;

Now it's useful to isolate the generated code in its own module, to isolate the generated code from the source code (e.g. to avoid naming collisions, leaking of use declarations, etc.). So I want the generated code to be something like this:

mod _Derivative_MyStruct {
    use super::MyStruct;
    impl Derivative for MyStruct { }
}

However, the example above fails if the struct is defined in a function, due to the problem at the top. e.g. this won't work:

fn my_fn() {
    #[derive(Derivative)];
    struct MyStruct;
}

as it expands into:

fn my_fn() {
    #[derive(Derivative)];
    struct MyStruct;
    mod _Derivative_MyStruct {
        use super::MyStruct; // error
        impl Derivative for MyStruct {}
    }
}

This is especially troublesome for doctests, as these are implicitly wrapped in a function. E.g. this will give the unresolved import problem:

/// Some interesting documentation
/// ```
/// #[derive(Derivative)]
/// struct MyStruct;
/// ```

Without the ability to refer to the outer scope, I either need to give up isolation, or require wrapping in modules at the call site. I'd like to avoid this.

like image 490
Tiddo Avatar asked Aug 15 '26 23:08

Tiddo


1 Answers

This is issue #79260. I don't think there is a solution.

However, you can define the nested items inside an unnamed const (const _: () = { /* code */ };) instead of a module. This prevents name collisions and is the idiomatic thing to do in macros that need to define names. Do note however that this does not have a way to refer to items inside the const from outside it.

like image 88
Chayim Friedman Avatar answered Aug 18 '26 06:08

Chayim Friedman