Is is possible to create a struct enum variant in a functional macro on stable?

enum MyError
{
   Root(Base)
}

enum MyError2
{
   Root{source: Base}
}

struct Base;


macro_rules! impl_base_error
{
   ($ty:ty) => 
   {
      impl From<Base> for $ty 
      {
         fn from( source: Base ) -> Self 
         {
            <$ty>::Root(source)
         }
      }
   }
}


macro_rules! impl_base_error2
{
   ($ty:ty) => 
   {
      impl From<Base> for $ty 
      {
         fn from( source: Base ) -> Self 
         {
            <$ty>::Root{ source }
         }
      }
   }
}

impl_base_error!(MyError);
impl_base_error2!(MyError2);

This will throw:

   Compiling playground v0.0.1 (/playground)
error[E0658]: usage of qualified paths in this context is experimental
  --> src/main.rs:37:13
   |
37 |             <$ty>::Root{ source: err }
   |             ^^^^^^^^^^^
...
44 | impl_base_error2!(MyError2);
   | --------------------------- in this macro invocation
   |
   = note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
   = note: this error originates in the macro `impl_base_error2` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0658`.
error: could not compile `playground` due to previous error

The tuple variant is fine, but the struct one isn't.

Playground

I am not sure why you can't use $ty in this context, but one way to achieve what you are doing is by using Self to refer to the type, like this: Rust Playground

Another workaround is:

macro_rules! impl_base_error2 {
    ($ty:ty) => {
        impl From<Base> for $ty {
            fn from(err: Base) -> Self {
                use $ty::*;
                Root { source: err.into() }
            }
        }
    };
}

Thanks. That does seem to work. For some reason you can use ::* but when using $ty::Root{ source } the compiler will suggest to use <$ty> and when trying to use $ty::Root, it will also fail...

So yes, I probably end up silencing clippy for glob import and use this.

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.