This question is now obsolete because this feature has been implemented. Related answer.
The following Rust code fails to compile:
enum Foo {
If the enum name Foo
is in reality long and you want to avoid repeating it across the implementation, you have two options:
use LongEnumName as Short
at module level. This will allow you to return Short::Bar
at the end of f
.use LongEnumName::*
at module level, allowing an even shorter Bar
.If you omit pub
, the imports will be internal and won't affect the public API of the module.
An important thing to note is that the error said associated item. enum Foo { Baz }
doesn't have associated items. A trait can have an associated item:
trait FooBaz { type Baz }
// ^~~~~~~~ - associated item
To summarize:
Why can't
Self
be used in this situation?
Because of this issue. RFC 2338 has not been implemented yet.
Self
seems to act as a type alias, albeit with some modifications.
Where exactly can
Self
be used?
Self can only be used in traits and impl
s. This code:
struct X {
f: i32,
x: &Self,
}
Outputs the following:
error[E0411]: cannot find type `Self` in this scope
--> src/main.rs:3:9
|
3 | x: &Self,
| ^^^^ `Self` is only available in traits and impls
This is possibly a temporary situation and might change in the future!
More precisely, Self
should be used only as part of method signature (e.g. fn self_in_self_out(&self) -> Self
) or to access an associated type:
enum Foo {
Baz,
}
trait FooBaz {
type Baz;
fn b(&self) -> Self::Baz; // Valid use of `Self` as method argument and method output
}
impl FooBaz for Foo {
type Baz = Foo;
fn b(&self) -> Self::Baz {
let x = Foo::Baz as Self::Baz; // You can use associated type, but it's just a type
x
}
}
I think user4815162342 covered the rest of the answer best.
Enum constructors != associated items.
It is a known issue, but it's not expected to be fixed, at least not in the foreseeable future. From what I have gathered it is not trivial to just allow this to work; at this point it is more likely that the related documentation or the error message will be improved.
There is little documentation I could find on the topic of associated items in general; The Rust Book has a chapter on associated types, though. In addition, there are plenty of good answers about Self
in this related question.
There is an experimental feature that would make your example work without any other changes. You can try it out in a nightly build of Rust by adding this in your main file:
#![feature(type_alias_enum_variants)]
You can follow the progress of the feature towards stabilisation in its tracking issue.
This is now possible as of version 1.37.