The first pre-RFC for a similiar feature was published by @Fishrock123 at [Pre-RFC] Inferred Enum Type. I suppose it was not well accepted due to readability or language confusion (.M
, _::M
). I will try using the reserved word enum
as a path prefix, as in enum::M
.
- Feature Name:
inferred_member
- Start Date: 2023-11-25
- RFC PR: rust-lang/rfcs#0000
- Rust Issue: rust-lang/rust#0000
Summary
Support for the path enum::M
, indicating a member M
of an inferred enum or struct.
Throughout this proposal, enum interchangeably refers to enums and structs (including bitwise sets designed through the bitflags
crate).
Motivation
This path syntax allows shortening the reference or initialization of enum members. When using this syntax, it is not required to:
- import the enum or the enum's member into scope;
- fully qualify the enum's member
Guide-level explanation
It is possible to refer.to a constant, unit, tuple, or struct variant using an inferred enum member path in the form enum::M
.
enum MyEnum {
MyVariant1,
MyVariant2(f64),
MyVariant3 { x: f64 },
}
let value: MyEnum = enum::MyVariant1;
let value: MyEnum = enum::MyVariant2(10.0);
let value: MyEnum = enum::MyVariant3 { x: 10.0 };
enum::M
paths may be useful for avoiding including a library's variant or enum into scope:
use restaurant::FoodCategory;
enum::M
paths may be useful when constructing nodes:
enum::ExpressionStatement(with! {
expression: enum::NumericLiteral(10.0),
})
Reference-level explanation
- The
enum::M
path is allowed within- Matching patterns
- Unit variant usages (
enum::M
) - Tuple variant usages (
enum::M()
) - Struct variant usages (
enum::M {}
)
- The
enum::M
path resolves either to a variant of an inferred enum or a constant from an inferred struct. It is a compile-time error if the expression has no expected enum, that is, a type annotation is required. - Syntax ambiguity: an expression slightly conflicts with items due to the
enum::
path. They are disambiguated when anenum
item starts with theenum
token and the immediately following token is either::
or an identifier.
Drawbacks
It is not clear whether the proposal resolves the problem of long enum paths. Compared to the first proposal, this adds extra three characters to the path; however it adds the same benefits from the other proposal (scope and conciseness).
Other drawbacks:
r#enum::Variant
is already allowed, meaningVariant
from moduleenum
Rationale and alternatives
The first proposal suggested a _::M
form instead of enum::M
; compared to that proposal, this proposal does not use a punctuator and resembles module paths such as crate
, super
and self
. The advantage of this proposal is readability and the disadvantage is more three keystrokes effort for the programmer.
Prior art
ActionScript 3 has received a proposal for simple enums and compile-time implicit conversion from string literal to enums where applicable:
enum MyEnum {
const MEMBER_1;
}
const value: MyEnum = "member1";
The same cannot be applied to Rust due to naming conventions and also due to tuple and struct variants:
let value: MyEnum = "MyVariant1";
let value: MyEnum = "MyVariant2"(10.0);
let value: MyEnum = "MyVariant3" { x: 10.0 };
Unresolved questions
N/A
Future possibilities
N/A