Description
Currently the following is not allowed:
fn main() {
#[derive(Debug)]
enum Foo { A, B }
type Bar = Foo;
println!("{:?}", Bar::A);
}
This code produces the following error:
error: no associated item named `A` found for type `main::Foo` in the current scope
I can understand why this error occurs: variant access such as Foo::A
occurs via a path, and type Bar = Foo
simply aliases the type, not the path accessor, thus an error is produced when trying to access an enum's variants via an alias.
In examples like the one above this normally isn't a huge issue as it is possible to pub use Foo as Bar
instead, which accomplishes the same thing in practise.
However, in practise I often come across cases where pub use
does not suffice. The most pressing use-case I've come across is when Foo
has a type parameter, and I want to create an alias of Foo
with the type parameter filled, i.e.
#[derive(Debug)]
pub enum Foo<T> { A(T), B }
pub type Bar = Foo<i32>;
pub fn baz() -> Bar {
Bar::A(0) // error
}
fn main() {
println!("{:?}", baz());
}
Here I want to expose Bar
from my API as if it were a Foo<i32>
when it comes to its use as a type as well as variant access. Doing a type alias (as above) allows for using Bar
in signatures without issues (see the fn baz
signature) however I cannot access the variants using Bar
, meaning I would have to also require a user to import Foo
in case they wish to access variants. Alternatively, if I instead pub use foo::Foo as Bar
I can now access variants using Bar
without issue, however the type parameter is no longer filled, meaning the fn baz
signature no longer works and I'm unable to express through my API that Bar
should always be Foo<i32>
and not Foo<T>
.
It would be really nice if we could either:
pub use Foo<i32> as Bar;
orpub type Bar = Foo<i32>; // This allows variant access via Bar::A