Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upMatching on an enum shouldn't require full scoping inside the match #421
Comments
rust-highfive
referenced this issue
Oct 27, 2014
Closed
Matching on an enum shouldn't require full scoping inside the match #16681
nrc
changed the title
[CLOSED] Matching on an enum shouldn't require full scoping inside the match
Matching on an enum shouldn't require full scoping inside the match
Oct 27, 2014
This comment has been minimized.
This comment has been minimized.
leodasvacas
commented
Jul 3, 2015
|
Don't know what the status is on this, but as a user I'm very much in favor |
This comment has been minimized.
This comment has been minimized.
|
I’m somewhat against, because for uncomfortably big matches/enum paths you can use something resembling following:
You don’t have to import these at the top level, function or block-level import is fine. Also library/module may export unqualified enum variants as well. Also original motivation does not apply as much anymore either, because glob imports are stable. |
This comment has been minimized.
This comment has been minimized.
|
I see You could always write it out long form if you don't like it compact. |
This comment has been minimized.
This comment has been minimized.
|
This would be nice, but what about derivations? E.g. this would require importing names from two enums, with more potential for name collision:
|
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
Nov 10, 2016
|
Why should we import instead of rewrite match (enum1, enum2) {
(A, X) => {},
(B, X) => {},
(B, Y) => {},
(_, _) => {},
}becomes match (enum1, enum2) {
(typeof(enum1)::A, typeof(enum2)::X) => {},
(typeof(enum1)::B, typeof(enum2)::X) => {},
(typeof(enum1)::B, typeof(enum2)::Y) => {},
(_, _) => {},
}I like the idea. It eases |
This comment has been minimized.
This comment has been minimized.
|
What if |
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
Nov 10, 2016
enum E {
A
}
fn main() {
match E::A {
0 => {},
_ => {}
}
}returns:
So it isn't a problem. |
This comment has been minimized.
This comment has been minimized.
#[derive(PartialEq, Eq)]
enum E {
A,
}
const X: E = E::A;
fn main() {
match E::A {
X => {}
}
} |
This comment has been minimized.
This comment has been minimized.
|
Worse: #[derive(PartialEq, Eq)]
enum E { A, B, C }
const A: E = E::B; // counter-intuitive but not illegal
fn main() {
match E::A {
A => { /* which A? */ }
_ => {}
}
}Backwards compatibility requires that pattern |
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
Nov 13, 2016
|
I think that the opinions from @sfackler, @dhardy are important. I have no counter-argument. enum E {
case A, B
}
switch E.A {
.A: /* code to handle E.A */
}But we cannot do match E::A {
::A => {}
}because |
This comment has been minimized.
This comment has been minimized.
burdges
commented
Nov 13, 2016
•
|
Arguably, we should make this existing ambiguity an error, or at least a warning that said which it picked, anyways :
I think that weakens the case against presented thus far. A priori, I kinda suspect there is more to be gained from stuff like It's a whole different matter if this interacts poorly with say return type inference for Also, I could imagine folks wanting trait enums eventually like they are now going for trait fields over getters and setters. I could imagine An alternative might be a weak convention that enum names be kept short in libraries perhaps. |
This comment has been minimized.
This comment has been minimized.
|
As always, the backwards-compatible way to solve ambiguities is to only give meaning to code that doesn't currently compile, i.e. when something doesn't resolve within a pattern. In fact, the any of the options expressed here that are anything like syntactical rewrites before name resoluton are quite inactionable. Rewriting a
|
This comment has been minimized.
This comment has been minimized.
|
F# in comparison is slightly better but not much smarter. It doesn't require full scoping unless if finds an ambiguity. It would look like this in Rust: enum Two {
Left,
Right
}
enum Four {
Left,
Right,
Top,
Bottom
}
fn main() {
let four = Four::Top;
match four {
Four::Left => {},
Four::Right => {},
// ^ Sees these as name collisions when in actuality they should not be
Top => {},
Bottom => {},
}
} |
This comment has been minimized.
This comment has been minimized.
|
@mdinger Right, and Rust could've done this if it said that |
This comment has been minimized.
This comment has been minimized.
|
Oh, I didn't recognize your previous statement as ranking this as currently implausible (probably due to complete lack of understanding of the compiler internals). It's pretty unfortunate something this convenient would be that compatibility breaking. |
This comment has been minimized.
This comment has been minimized.
burdges
commented
Nov 15, 2016
|
If
I'm dubious that'd ever work because the Anyways, if you're worried about conflicting imports inside the
|
Rufflewind
referenced this issue
Mar 17, 2017
Closed
Enum name elison through inferred variant constructors #1949
This was referenced Apr 14, 2017
Centril
added
the
T-lang
label
Feb 23, 2018
This comment has been minimized.
This comment has been minimized.
Boscop
commented
Apr 28, 2018
|
Could it be done in epochs? #[derive(PartialEq, Eq)]
enum E { A, B, C }
const A: E = E::B; // counter-intuitive but not illegal
fn main() {
match E::A {
A => { /* which A? */ }
_ => {}
}
}In the 2nd epoch, this would compile: enum Two {
Left,
Right
}
enum Four {
Left,
Right,
Top,
Bottom
}
fn main() {
let four = Four::Top;
match four { // no constants with same name, type is Four, so it knows these are from Four
Left => {},
Right => {},
Top => {},
Bottom => {},
}
}So the purpose of the warning in epoch 1 is to allow people to adjust their code before the change is made in epoch 2. |
This comment has been minimized.
This comment has been minimized.
|
I don't think we've got anything actionable (or indeed desirable due to the ad-hoc nature of what is proposed) and I am not particularly interested in using the edition mechanism for breakage. Therefore, I'm closing this. |
rust-highfive commentedOct 27, 2014
Friday Aug 22, 2014 at 18:16 GMT
For earlier discussion, see rust-lang/rust#16681
This issue was labelled with: in the Rust repository
I was trying to de-glob libsyntax (rust-lang/rust#11983) but this is a real nuisance there. The enums are much much bigger than this.
I hope this is clear. Let me know if it isn't.