-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Constants involving dereferencing in pattern matching #25574
Comments
A rather easy task for a new compiler hacker (const_eval::const_expr_to_pat). |
I would love to try take a work on this, plus I would qualify as a new compiler hacker. I've been going through the code linked above, and I have some idea of what to do, although I will undoubtedly have questions later. |
@barca Happy to mentor, let me know how it goes! Thanks! |
@jakub- While I'm fairly confident about the code I've written to solve this issue, However I'm running into the issue of compiling the language from source. Its extremely slow to compile, and quite frustrating when a serious error occurs(which has unfortunately happened quite frequently). I was wondering if you had any tricks for speeding up this overall process. Thanks |
@jakub- So, I've been struggling with this issue, but have been actively working on it. up until now I have been trying to dereference the u8 literals or the vec that holds them, however have been unsuccessful in this. While it is more than possible that I have made a mistake in my implementation, I was wondering if you had an idea of how to approach this issue. |
@barca on slow compiles, there's a few things you can do, make sure you're building with |
@barca please post your patch and I'll take a look, hard for me to know exactly what the problem is without seeing the code. |
@nrc thanks, I was able to find some blogs, I've been doing 4 jobs seems to work fast enough. |
@barca I think you're pretty much on the right track. The pattern you end up with should be a PatLit wrapping an ExprVec, then you just need to convert your Vec of u8s into a Vec of LitInts (wrapped in ExprInts). There will be a little bit of a dance with |
❤️ @barca ping me on irc if you need any more help |
I came accross this issue and got stuck on it as an inexperienced Rust user. From my understanding the piece of code mentioned in the issue should be equal to the next one where I substitute the constant's value directly into the pattern: fn main() {
match *b"xxxx" {
*b"fooo" => {},
_ => {}
}
} It fails with
which means (as far as I understand) that it is not enough to just add constant-to-pattern expansion but also modify match to support matching of dereferenced literals. Is it so or I missed something? |
@istaheev it is not, as literals in patterns are more limited than constant expressions. That said, I believe what @nrc is suggesting (turning |
I'm essentially done with the fix, should I continue to work on it/ push it if you are going to change the structure completely? |
@barca such restructuring may not happen for another couple months (or even years), so don't mind me and feel free to open a PR. |
@barca: yes please! |
@barca My apologies for ignoring your messages, the last month's been merciless for me time wise! |
I was wondering what the current state was for the issue. I'd be interested in contributing if more work needs to be done! |
@code-ape actually still working on the issue, although haven't had time to do it in the last few days since I was moving. I believe I am fairly close to solution, although am eternally optimistic regarding such issues. |
@tsion The MIR has landed (and it has its own pattern lowering), though I don't know if it supports this usecase correctly. |
In general the treatment of constants in pattern checking is somewhat broken, actually (at least in my opinion). I've been meaning to write up something on this, will do so soon, but the TL;DR is that we always use structural equality, even if (e.g.) the That said, I imagine this use case ought to work, but there are many others that don't which I don't really think ought to work. I'm not sure I'd call this an E-easy bug, though, but I guess that's because I tend to think that we need to do more overhaul of our constant treatment (and especially in patterns). |
@eddyb @nikomatsakis Is this still E-easy or similar? I'd be interested in contributing if possible. |
@cramertj The transition to MIR-based constant evaluation should fix this. |
Ah, okay. Thanks. |
Triage: as far as I know, const evaluation is still undergoing an overhaul, I don't know if it's far enough along to work on this yet. |
Replace all const evaluation with miri * error reporting in constants prints a stacktrace through all called const fns * Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level) * can now use floating constants in patterns (previously only floating point literals were allowed) * the future compat lint is still produced for both cases * can index into constant arrays during const eval (previously feature gated) * can create a constant union value with field `a` and read from field `b` * can dereference references into constants * can create references inside constants (`const X: &u32 = &22`) * Tuple struct constructors can be used in constants * regression in const eval errors spans (some of these need improvements in mir debug info) * can cast floats to ints and vice versa (in constants, and even nan/inf constants) * Mir dump prints false/true instead of 0u8/1u8 * `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore. * Needs const propagation across projections * `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I` * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not) fixes #34997 (stack overflow with many constants) fixes #25574 (deref byte strings in patterns) fixes #27918 (broken mir ICE) fixes #46114 (ICE on struct constructors in patterns) fixes #37448 (`SomeStruct { foo } as SomeStruct`) fixes #43754 (`return` in const fn) fixes #41898 (tuple struct constructors) fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit) closes #29947 (const indexing stabilization) r? @eddyb
Replace all const evaluation with miri * error reporting in constants prints a stacktrace through all called const fns * Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level) * can now use floating constants in patterns (previously only floating point literals were allowed) * the future compat lint is still produced for both cases * can index into constant arrays during const eval (previously feature gated) * can create a constant union value with field `a` and read from field `b` * can dereference references into constants * can create references inside constants (`const X: &u32 = &22`) * Tuple struct constructors can be used in constants * regression in const eval errors spans (some of these need improvements in mir debug info) * can cast floats to ints and vice versa (in constants, and even nan/inf constants) * Mir dump prints false/true instead of 0u8/1u8 * `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore. * Needs const propagation across projections * `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I` * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not) fixes #34997 (stack overflow with many constants) fixes #25574 (deref byte strings in patterns) fixes #27918 (broken mir ICE) fixes #46114 (ICE on struct constructors in patterns) fixes #37448 (`SomeStruct { foo } as SomeStruct`) fixes #43754 (`return` in const fn) fixes #41898 (tuple struct constructors) fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit) closes #29947 (const indexing stabilization) fixes #45044 (pattern matching repeat expressions) r? @eddyb
Replace all const evaluation with miri * error reporting in constants prints a stacktrace through all called const fns * Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level) * can now use floating constants in patterns (previously only floating point literals were allowed) * the future compat lint is still produced for both cases * can index into constant arrays during const eval (previously feature gated) * can create a constant union value with field `a` and read from field `b` * can dereference references into constants * can create references inside constants (`const X: &u32 = &22`) * Tuple struct constructors can be used in constants * regression in const eval errors spans (some of these need improvements in mir debug info) * can cast floats to ints and vice versa (in constants, and even nan/inf constants) * Mir dump prints false/true instead of 0u8/1u8 * `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore. * Needs const propagation across projections * `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I` * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not) * can use `union`s to implement `transmute` for `Copy` types in constants without a feature gate. With all the greatness and nasal demons that come with this. fixes #34997 (stack overflow with many constants) fixes #25574 (deref byte strings in patterns) fixes #27918 (broken mir ICE) fixes #46114 (ICE on struct constructors in patterns) fixes #37448 (`SomeStruct { foo } as SomeStruct`) fixes #43754 (`return` in const fn) fixes #41898 (tuple struct constructors) fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit) closes #29947 (const indexing stabilization) fixes #45044 (pattern matching repeat expressions) fixes #47971 (ICE on const fn + references) r? @eddyb
Replace all const evaluation with miri * error reporting in constants prints a stacktrace through all called const fns * Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level) * can now use floating constants in patterns (previously only floating point literals were allowed) * the future compat lint is still produced for both cases * can index into constant arrays during const eval (previously feature gated) * can create a constant union value with field `a` and read from field `b` * can dereference references into constants * can create references inside constants (`const X: &u32 = &22`) * Tuple struct constructors can be used in constants * regression in const eval errors spans (some of these need improvements in mir debug info) * can cast floats to ints and vice versa (in constants, and even nan/inf constants) * Mir dump prints false/true instead of 0u8/1u8 * `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore. * Needs const propagation across projections * `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I` * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not) * can use `union`s to implement `transmute` for `Copy` types in constants without a feature gate. With all the greatness and nasal demons that come with this. * can convert integers to `&'static T` in constants (useful for embedded) fixes #34997 (stack overflow with many constants) fixes #25574 (deref byte strings in patterns) fixes #27918 (broken mir ICE) fixes #46114 (ICE on struct constructors in patterns) fixes #37448 (`SomeStruct { foo } as SomeStruct`) fixes #43754 (`return` in const fn) fixes #41898 (tuple struct constructors) fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit) closes #29947 (const indexing stabilization) fixes #45044 (pattern matching repeat expressions) fixes #47971 (ICE on const fn + references) fixes #48081 (ICE on cyclic assoc const error) fixes #48746 (nonhelpful error message with unions) r? @eddyb even though 1k loc are added in tests, this PR reduces the loc in this repository by 700
Replace all const evaluation with miri * error reporting in constants prints a stacktrace through all called const fns * Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level) * can now use floating constants in patterns (previously only floating point literals were allowed) * the future compat lint is still produced for both cases * can index into constant arrays during const eval (previously feature gated) * can create a constant union value with field `a` and read from field `b` * can dereference references into constants * can create references inside constants (`const X: &u32 = &22`) * Tuple struct constructors can be used in constants * regression in const eval errors spans (some of these need improvements in mir debug info) * can cast floats to ints and vice versa (in constants, and even nan/inf constants) * Mir dump prints false/true instead of 0u8/1u8 * `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore. * Needs const propagation across projections * `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I` * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not) * can use `union`s to implement `transmute` for `Copy` types in constants without a feature gate. With all the greatness and nasal demons that come with this. * can convert integers to `&'static T` in constants (useful for embedded) fixes #34997 (stack overflow with many constants) fixes #25574 (deref byte strings in patterns) fixes #27918 (broken mir ICE) fixes #46114 (ICE on struct constructors in patterns) fixes #37448 (`SomeStruct { foo } as SomeStruct`) fixes #43754 (`return` in const fn) fixes #41898 (tuple struct constructors) fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit) closes #29947 (const indexing stabilization) fixes #45044 (pattern matching repeat expressions) fixes #47971 (ICE on const fn + references) fixes #48081 (ICE on cyclic assoc const error) fixes #48746 (nonhelpful error message with unions) r? @eddyb even though 1k loc are added in tests, this PR reduces the loc in this repository by 700
Constants that dereference string literals cannot be currently used for pattern matching as show below:
Such constants can be used in other contexts without any problem. It is inconsistent, and a very prominent use case is missing.
The text was updated successfully, but these errors were encountered: