It seems that function inlining heuristics fail in the following use case and does not inline when it should. Given huge match statement:
pub enum XXX {
A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, K1, L1, M1, N1, O1, P1, Q1, R1, S1, T1, U1, V1, W1, X1, Y1, Z1,
A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2, V2, W2, X2, Y2, Z2,
}
impl std::convert::TryFrom<u8> for XXX {
type Error = ();
fn try_from(x: u8) -> Result<Self, Self::Error> {
match () {
_ if x == XXX::A1 as u8 => Ok(XXX::A1),
_ if x == XXX::B1 as u8 => Ok(XXX::B1),
_ if x == XXX::C1 as u8 => Ok(XXX::C1),
_ if x == XXX::D1 as u8 => Ok(XXX::D1),
_ if x == XXX::E1 as u8 => Ok(XXX::E1),
_ if x == XXX::F1 as u8 => Ok(XXX::F1),
_ if x == XXX::G1 as u8 => Ok(XXX::G1),
_ if x == XXX::H1 as u8 => Ok(XXX::H1),
_ if x == XXX::I1 as u8 => Ok(XXX::I1),
_ if x == XXX::J1 as u8 => Ok(XXX::J1),
_ if x == XXX::K1 as u8 => Ok(XXX::K1),
_ if x == XXX::L1 as u8 => Ok(XXX::L1),
_ if x == XXX::M1 as u8 => Ok(XXX::M1),
_ if x == XXX::N1 as u8 => Ok(XXX::N1),
_ if x == XXX::O1 as u8 => Ok(XXX::O1),
_ if x == XXX::P1 as u8 => Ok(XXX::P1),
_ if x == XXX::Q1 as u8 => Ok(XXX::Q1),
_ if x == XXX::R1 as u8 => Ok(XXX::R1),
_ if x == XXX::S1 as u8 => Ok(XXX::S1),
_ if x == XXX::T1 as u8 => Ok(XXX::T1),
_ if x == XXX::U1 as u8 => Ok(XXX::U1),
_ if x == XXX::V1 as u8 => Ok(XXX::V1),
_ if x == XXX::W1 as u8 => Ok(XXX::W1),
_ if x == XXX::X1 as u8 => Ok(XXX::X1),
_ if x == XXX::Y1 as u8 => Ok(XXX::Y1),
_ if x == XXX::Z1 as u8 => Ok(XXX::Z1),
_ if x == XXX::A2 as u8 => Ok(XXX::A2),
_ if x == XXX::B2 as u8 => Ok(XXX::B2),
_ if x == XXX::C2 as u8 => Ok(XXX::C2),
_ if x == XXX::D2 as u8 => Ok(XXX::D2),
_ if x == XXX::E2 as u8 => Ok(XXX::E2),
_ if x == XXX::F2 as u8 => Ok(XXX::F2),
_ if x == XXX::G2 as u8 => Ok(XXX::G2),
_ if x == XXX::H2 as u8 => Ok(XXX::H2),
_ if x == XXX::I2 as u8 => Ok(XXX::I2),
_ if x == XXX::J2 as u8 => Ok(XXX::J2),
_ if x == XXX::K2 as u8 => Ok(XXX::K2),
_ if x == XXX::L2 as u8 => Ok(XXX::L2),
_ if x == XXX::M2 as u8 => Ok(XXX::M2),
_ if x == XXX::N2 as u8 => Ok(XXX::N2),
_ if x == XXX::O2 as u8 => Ok(XXX::O2),
_ if x == XXX::P2 as u8 => Ok(XXX::P2),
_ if x == XXX::Q2 as u8 => Ok(XXX::Q2),
_ if x == XXX::R2 as u8 => Ok(XXX::R2),
_ if x == XXX::S2 as u8 => Ok(XXX::S2),
_ if x == XXX::T2 as u8 => Ok(XXX::T2),
_ if x == XXX::U2 as u8 => Ok(XXX::U2),
_ if x == XXX::V2 as u8 => Ok(XXX::V2),
_ if x == XXX::W2 as u8 => Ok(XXX::W2),
_ if x == XXX::X2 as u8 => Ok(XXX::X2),
_ if x == XXX::Y2 as u8 => Ok(XXX::Y2),
_ if x == XXX::Z2 as u8 => Ok(XXX::Z2),
_ => Err(()),
}
}
}
rustc 1.74.1 (a28077b28 2023-12-04)
binary: rustc
commit-hash: a28077b28a02b92985b3a3faecf92813155f1ea1
commit-date: 2023-12-04
host: x86_64-unknown-linux-gnu
release: 1.74.1
LLVM version: 17.0.4
It seems that function inlining heuristics fail in the following use case and does not inline when it should. Given huge
matchstatement:Rust does a great job of boiling it down:
But it doesn't inline this properly when used in other functions:
generates:
An explicit
#[inline]given totry_fromresults in this instead:rustc --version --verbose: