Skip to content
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

Confusing error message when matching on &str in const fn #90237

Closed
ilyvion opened this issue Oct 24, 2021 · 3 comments · Fixed by #112232
Closed

Confusing error message when matching on &str in const fn #90237

ilyvion opened this issue Oct 24, 2021 · 3 comments · Fixed by #112232
Assignees
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ilyvion
Copy link

ilyvion commented Oct 24, 2021

Given the following code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=bc51fb79544b1be00dd8a4285103ff07

const fn foo(input: &'static str) {
    match input {
        "a" => (),
        _ => (),
    }
}

The current output is:

error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 --> src/lib.rs:3:9
  |
3 |         "a" => (),
  |         ^^^

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 rustc has 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.

@ilyvion ilyvion added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 24, 2021
@PatchMixolydic
Copy link
Contributor

I'm not familiar with how matching on &str is implemented, so this is pure conjecture, but the "call" might be an implicit call to input.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

@rustbot rustbot added A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) D-confusing Diagnostics: Confusing error or lint that should be reworked. labels Oct 25, 2021
@fee1-dead fee1-dead self-assigned this Nov 3, 2021
@detly
Copy link

detly commented Sep 29, 2022

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 error

@jnnnnn
Copy link

jnnnnn commented May 17, 2023

I ran into this as well. It's definitely calling <str as PartialEq>::eq as part of the match. The way to prove so is to look at the MIR (and remove const so 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>::eq probably can't be const until #67792 lands.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 18, 2023
…sg, r=b-naber

Better error for non const `PartialEq` call generated by `match`

Resolves rust-lang#90237
@bors bors closed this as completed in 31d1fbf Jun 20, 2023
flip1995 pushed a commit to flip1995/rust that referenced this issue Jun 30, 2023
…sg, r=b-naber

Better error for non const `PartialEq` call generated by `match`

Resolves rust-lang#90237
bjorn3 pushed a commit to bjorn3/rust that referenced this issue Jul 22, 2023
…sg, r=b-naber

Better error for non const `PartialEq` call generated by `match`

Resolves rust-lang#90237
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants