Match gives error despite all cases being covered

I have the following match expression

    let mut next_byte = [0; 1];
    let _ = conn.read(&mut next_byte).map_err(IoError)?;
    let first_byte = next_byte[0];
    let chunk_type = first_byte & 0xc0;
    let id = first_byte & 0x3f;
    match id {
        stream_id if stream_id > 1 => {
            return Ok(ChunkHeader {
                chunk_type,
                stream_id: stream_id as usize,
            })
        }
        0 => {
            let _ = conn.read(&mut next_byte).map_err(IoError)?;
            return Ok(ChunkHeader {
                chunk_type,
                stream_id: next_byte[0] as usize + 64, //next byte
            });
        }
        1 => {
            let mut next_two_bytes = [0; 2];
            let _ = conn.read(&mut next_two_bytes).map_err(IoError)?;
            let stream_id = u16::from_be_bytes(next_two_bytes) as usize;
            Ok(ChunkHeader {
                chunk_type,
                stream_id,
            })
        }
    }

Anything greater than 1 is handled by the first arm and 0 and 1 are handled by the others yet compiler keeps refusing to compile stating that I hadnt covered all possible cases.

Is there something I am missing or is this a copiler bug ?

Rustc doesn't analyze the if guards, so it sees it as "unknown, 0, 1" and that's why it wants 2+ covered.

You can add _ => unreachable!() or an unsafe variant of it that will be optimized away.

1 Like

thanks

In this case, you can also just rearrange the branches.

match id {
    0 => { ... }
    1 => { ... }
    stream_id => { ... }
}
4 Likes

Actually yes I dont know why I am using a guard there it doesnt make much sense :smiley: