Skip to content

Associated-const ranges in patterns are miscompiled in beta #57960

Closed
@bytwise

Description

@bytwise

This code demonstrates the problem (playpen):

#![allow(dead_code)]

trait Range {
    const FIRST: u8;
    const LAST: u8;
}

struct OneDigit;
impl Range for OneDigit {
    const FIRST: u8 = 0;
    const LAST: u8 = 9;
}

struct TwoDigits;
impl Range for TwoDigits {
    const FIRST: u8 = 10;
    const LAST: u8 = 99;
}

struct ThreeDigits;
impl Range for ThreeDigits {
    const FIRST: u8 = 100;
    const LAST: u8 = 255;
}

fn digits(x: u8) -> u32 {
    match x {
        OneDigit::FIRST...OneDigit::LAST => 1,
        TwoDigits::FIRST...TwoDigits::LAST => 2,
        ThreeDigits::FIRST...ThreeDigits::LAST => 3,
        _ => unreachable!(),
    }
}

fn main() {
    println!("{}", digits(100));
}

With stable-1.32.0 it prints 3. With beta-1.33.0 it wrongly prints 1.

Beta also produces these wrong warnings:

warning: unreachable pattern
  --> src/main.rs:29:9
   |
29 |         TwoDigits::FIRST...TwoDigits::LAST => 2,
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: #[warn(unreachable_patterns)] on by default

warning: unreachable pattern
  --> src/main.rs:30:9
   |
30 |         ThreeDigits::FIRST...ThreeDigits::LAST => 3,
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It seems that Rustc decides, that the first arm covers the whole range of a
u8 and optimizes out the other arms before they even reach MIR.

The code is very similar to this testcase.
But the testcase does not test that the other arms can be reached.

I was able to bisect the regression to #55937.

(This issue seems similar to #57894, but the reduced testcase there does not
use any associated consts)

Metadata

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)NLL-completeWorking towards the "valid code works" goalP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions