Pre-Pre-RFC: anonymous module / namespace ["Solved" by 2526-const-wildcard]

The idea is to be able to write something along the lines of:

mod /* unnamed! */ {
    // ...
}

Why ? The main place where I find this useful is for macros defining argument-specific custom items.

Example:

Imagine you have somewhere:

pub use self::my_type_implementation::MyType;
mod my_type_implementation;

and would like to check that the implemented MyType satisfies a given contract:

for<...> // all type/lifetime trait bounds parameters (optional)
    MyType
<...> // type/lifetime parameters for MyType (optional)
:
    Trait1 +
    Trait2<...> /* idem */ +
    ... +

For instance, let’s say MyType is parametric over T and want

for<T : Debug> MyType<T> : Debug

there are two ways to get that:

  1. A function (and thus, dead_code !) :

    fn check<T : Debug> () {  
        fn assert_Debug<Arg : Debug> () {}
        let _: fn() = assert_Debug::< MyType<T> >;
    }
    
  2. a trait:

    trait Check : Debug {}
    impl<T : Debug> Check for MyType<T> {}
    

Both solutions can be generalized with a macro, but they pollute the current namespace

by defining a new item (a function or a trait). Thus, for the macro to be used, it must either: only be safe to call within an empty module that the caller sets up (horrible!); take a free identifier $ident:ident and then expand to

mod $ident {
    use super::*;
    // actual contents go here
}

(better, but remains the problem of the fresh/available identifier);

or use something like the ::paste crate to forge your own (hopefully unique!) identifier from the arguments of the macro (hacky + adds a dependency)

The solution

Since we are not exporting any of the defined items, we don’t actually need to have a usable name for the module / namespace : in the same way that closure types are anonymous, it would be great to be able to have an anonymous module construct allowing to define the contents of the aforementioned macro as:

mod /*unnamed !*/ {
    use super::*;
    // actual contents go here
}

with the given property, of course, that multiple anonymous modules can live next to another:

//! The following would be valid:

// 1st anonymous module,
mod {}

// 2nd anonymous module,
mod {}

The accepted (and implemented) const _: () = { /* items */ }; RFC allows this usecase with minimal extra ovehead.

5 Likes

Awesome!!

I didn’t know of underscore_const_names but it is exactly what I was looking for (sometimes I don’t need a whole namespace but just some const typecheck and this also fits that need). Looking forward for an early stabilization then :slight_smile:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.