-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Matching on an enum shouldn't require full scoping inside the match #421
Comments
Don't know what the status is on this, but as a user I'm very much in favor 👍 |
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. |
I see You could always write it out long form if you don't like it compact. |
This would be nice, but what about derivations? E.g. this would require importing names from two enums, with more potential for name collision:
|
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 |
What if |
enum E {
A
}
fn main() {
match E::A {
0 => {},
_ => {}
}
} returns:
So it isn't a problem. |
#[derive(PartialEq, Eq)]
enum E {
A,
}
const X: E = E::A;
fn main() {
match E::A {
X => {}
}
} |
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 |
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 |
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. |
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
|
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 => {},
}
} |
@mdinger Right, and Rust could've done this if it said that |
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. |
If
I'm dubious that'd ever work because the Anyways, if you're worried about conflicting imports inside the
|
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. |
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. |
…ontroller-props Deprecate Application Controller Router Properties
Issue by mdinger
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.
The text was updated successfully, but these errors were encountered: