Skip to content

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

@ilyvion

Description

@ilyvion

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.

Activity

added
A-diagnosticsArea: Messages for errors, warnings, and lints
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Oct 24, 2021
PatchMixolydic

PatchMixolydic commented on Oct 25, 2021

@PatchMixolydic
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

added
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)
D-confusingDiagnostics: Confusing error or lint that should be reworked.
on Oct 25, 2021
self-assigned this
on Nov 3, 2021
detly

detly commented on Sep 29, 2022

@detly

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

jnnnnn commented on May 17, 2023

@jnnnnn

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.

added a commit that references this issue on Jun 18, 2023
7b91275
added a commit that references this issue on Jun 20, 2023
31d1fbf
added a commit that references this issue on Jun 30, 2023
9a65f46
added a commit that references this issue on Jul 22, 2023
7ba31b9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-diagnosticsArea: Messages for errors, warnings, and lintsD-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @detly@jnnnnn@ilyvion@PatchMixolydic@fee1-dead

    Issue actions

      Confusing error message when matching on `&str` in `const fn` · Issue #90237 · rust-lang/rust