Repository navigation
Confusing error message when matching on &str in const fn #90237
Description
Activity
- addedA-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Oct 24, 2021 I'm not familiar with how matching on
&stris implemented, so this is pure conjecture, but the "call" might be an implicit call toinput.eq("a"). The==operator issues the same confusing diagnostic (playground):const fn foo(input: &'static str) { input == "a"; }
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants --> src/lib.rs:2:5 | 2 | input == "a"; | ^^^^^^^^^^^^@rustbot modify labels: +A-const-eval +D-confusing
Reacted by Alexander Krivács Schrøder and Jonathan Newnham- addedA-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)D-confusingDiagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint that should be reworked.
on Oct 25, 2021 Note also that a byte string literal is fine:
const fn decode_bytes(b: &[u8]) -> Option<u8> { match b { b"0" => Some(0), _ => None, } }
☝️ compiles on 1.64, but
const fn decode_string(s: &str) -> Option<u8> { match s { "0" => Some(0), _ => None, } }
...fails with:
error[[E0015]](https://doc.rust-lang.org/stable/error-index.html#E0015): cannot call non-const operator in constant functions --> src/lib.rs:3:9 | 3 | "0" => Some(0), | ^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants For more information about this error, try `rustc --explain E0015`. error: could not compile `playground` due to previous errorI ran into this as well. It's definitely calling
<str as PartialEq>::eqas part of the match. The way to prove so is to look at the MIR (and removeconstso the code compiles).The const_str crate gets around this by converting to bytes for the comparison.
Here's a working example: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=286b897bb518dec6617d3da197cd318b
Note, this seems related to #103040 .
<str as PartialEq>::eqprobably can't beconstuntil #67792 lands.- added a commit that references this issue
on Jun 18, 2023 - added a commit that references this issue
on Jun 20, 2023 - added a commit that references this issue
on Jun 30, 2023 - added a commit that references this issue
on Jul 22, 2023
Given the following code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=bc51fb79544b1be00dd8a4285103ff07
The current output is:
I feel like it's pretty self-explanatory, but this is obviously a very confusing error. A match arm for a string literal is not a "call" by any usual meaning of the word. In fact, I have no idea what actual objection
rustchas to this code, if any.As far as I can tell, this error is the same on all current versions of the compiler (stable, beta, nightly) per the submission of this issue.