-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Change exhaustiveness analysis to allow a pattern to specialize with multiple constructors #15186
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
Conversation
cc @edwardw |
After a chat with @alexcrichton on IRC, we concluded that feature gating may not be strictly necessary. I think I agree. |
@@ -50,7 +50,7 @@ fn main() { | |||
} | |||
let vec = vec!(0.5); | |||
let vec: &[f32] = vec.as_slice(); | |||
match vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered | |||
match vec { //~ ERROR non-exhaustive patterns: `[_]` not covered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a valid change in that both [] and [, _, _, _] are missing but so it happens that the algorithm picks the other one first now.
So, to be clear, a pattern like |
@huonw It's still valid Rust. But the exhaustive/reachable pattern type check pass will (or should if it doesn't yet) ignore it. It is however feature-gated in this PR, although I'm inclined to ungate it pending further research on if it's feasible to bring back that functionality. |
Ah, so what's the breaking change? Something like match x {
[] => a,
[.., _] => b,
} will complain about non-exhaustive patterns? (If so, could you add an explicit example, with an explicit rewriting (e.g. adding a |
Just my random thought, is @BurntSushi quickcheck useful to generate tests with more coverage here? Match |
@edwardw It's an interesting idea. Yes, the specialisation routine as well as is_useful() seem highly QuickCheckable to me. I'll see if I can come up with an example. Not sure about the logistics of using QuickCheck in rustc, though, but maybe this is how we could sneak it in to Rust. :-) One thing we can do to mitigate the impact of this is to allow both cons lists [x, ..y] and snoc lists [..x, y] in a match column but not at the same time. Maybe that'd be an acceptable restriction? In the future, I'd love the pattern matching to be more generalised. I think http://www.cs.cornell.edu/andru/papers/jmatch3/pldi13.pdf may be a good read for someone interested in this. |
@jakub- thanks for the pointer. A SMT solver in the pattern matching sounds reassuring :) And if we decide to ban lists such as [..xs, x] or [a, ..xs, b], or not allow [x, ..y] and [..x, y] in the same column, then there should be compile-fail tests covering such scenarios. Currently there isn't any. |
@edwardw Agreed, this is definitely not mergeable yet. I'll add plenty of tests. |
@huonw @edwardw Okay, so I pursued the idea of allowing snoc-style patterns as long as they're not intermixed. It added a bit more complexity to how patterns are checked but at least it's still sound. [a, ..x, b] patterns are now rejected altogether for var-length slices. It'd be possible to keep them in with the consequence of them not being properly sanity checked but it doesn't feel right to me. I really like the fact that Rust's exhaustiveness errors are accurate and not just warnings so maybe it's worth sacrificing that syntax. What do you think? |
I understand that regardless of the practicality of keeping it in or not, doing so would require an RFC first. |
This is blocked on rust-lang/rfcs#144. |
…ttern Slice patterns are different from the rest in that a single slice pattern does not have a distinct constructor if it contains a variable-length subslice pattern. For example, the pattern [a, b, ..tail] can match a slice of length 2, 3, 4 and so on. As a result, the decision tree for exhaustiveness and redundancy analysis should explore each of those constructors separately to determine if the pattern could be useful when specialized for any of them.
Integer inference. @pnkfelix Could you re-r+? Thanks! |
feat: don't add panics to error jump list by default To re-enable this, use "rust-analyzer.runnables.problemMatcher": [ "$rustc", "$rust-panic" ], setting. closes: rust-lang#14977
No description provided.