-
-
Notifications
You must be signed in to change notification settings - Fork 310
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
RFC: exhaustive matching idiom #694
Comments
Just out of curiosity, is there a simple (ish) example of a case for external code to be matching enough cases for test-exhaustive matching to be used? A visitor API is an obvious example, but I'd expect the visitor API to be provided by syn or whatever other crate is providing a nonexhsustive enum. |
Interesting. Presumably this means that the I would also like to see use cases where it's critical/important for folks to do exhaustive matching on a non-exhaustive enum. |
For example a prettyprinter. I think there is room for a low-effort formatted printing library that just does a newline and indentation level on every open curly brace, with a small number of other heuristics. I would use such a thing here so we don't have to build all of rustfmt and don't have to rely on the system's rustfmt which is inconsistent across different developers' machines and sometimes missing from nightly. |
For the simple pretty printer example specifically, I'd expect it to work directly on That said, I could see the syntax version of |
I think the sweet spot for fast-compiling code generators is somewhere between what that TokenStream code does and what rustfmt does. For example things like the punctuation in closures really needs there to be a syntax tree for structure rather than just TokenStream. let out = tokens.unwrap_or_else(|err| err.to_compile_error());
// ^^^^^ |
What This would let crate B have: match expr {
Expr::Array(e) => {...}
Expr::Assign(e) => {...}
...
Expr::Yield(e) => {...}
#[cfg(test)]
not_matched => unimplemented!("{:#?}", not_matched),
#[cfg(not(test))]
not_matched => { /* some sane fallback */ }
} |
@Centril that's definitely less good because downstream's tests will continue to pass even after we add a variant. The point is for them to notice that a variant has been added so that they can update their code, without breaking downstream's users in the interim. |
I had a chat with @Centril and here is my language based alternative proposal: rust-lang/rust#44109 (comment). |
Lines 247 to 251 in 436eb22
Maybe change the links in the code to instead point to rust-lang/rust#81657 |
I think it would be rust-lang/rust#89554 as that is actually in work |
Here is the pattern I would like to document and recommend for use cases that require exhaustive matching (which is uncommon, but they exist):
This way we fail your tests but don't break your library when adding a variant. I believe this has all the benefits of an exhaustive enum and all the benefits of a nonexhaustive enum for only a little effort.
FYI @zerakun @phaylon @BurntSushi from the reddit thread.
FYI @mystor for brainstorming.
FYI @Centril because language support for nonexhaustive would need to have at least these benefits before I would want to pick it up.
The text was updated successfully, but these errors were encountered: