Description
Current situation
Right now, enum types and their variants are scoped at the same level, which means this:
mod foo {
enum Speed {
Fast,
Slow
}
}
leads to these paths:
foo::Speed;
foo::Fast;
foo::Slow;
We will likely not change this, because it often makes working with enums easier, and because many languages with similar enum types work that way.
The problem
However, the restriction to a flat hierarchy currently leads to a lot of variants getting their type name embedded in the variant name to avoid collisions and/or ambiguity. For example, a random enum picked out of libsyntax reads like this:
pub enum Sigil {
BorrowedSigil,
OwnedSigil,
ManagedSigil
}
The possible solution
To improve this situation, it would be convenient to have a enum declaration syntax for scoping the variants under their type instead, like this:
mod foo {
enum mod Speed {
Fast,
Slow
}
}
foo::Speed;
foo::Speed::Fast;
foo::Speed::Slow;
The above example could then get rewritten to
pub enum mod Sigil {
Borrowed,
Owned,
Managed
}
and get used as Sigil::Borrowed
, Sigil::Owned
etc, or directly imported in the local scope if there is no collision.
Emulating it
You can currently kinda emulate it with
mod foo {
pub type Speed = self::Speed::Speed;
pub mod Speed {
pub enum Speed {
Fast,
Slow
}
}
}
but this is very verbose, complicated, and creates more definitions and moving parts than necessary.
Working example
This uses the workaround above to show how using such a scoped enum would look like in practice.
#[feature(globs)];
use foo::Speed;
mod foo {
pub type Speed = self::Speed::Speed;
pub mod Speed {
pub enum Speed {
Fast,
Slow
}
}
}
fn main() {
let a: Speed = Speed::Fast;
let b: Speed = Speed::Slow;
match a {
Speed::Fast => {}
Speed::Slow => {}
}
{
use foo::Speed::*;
match b {
Fast => {}
Slow => {}
}
}
}