Stream: beginners

Topic: Compile time evaluation of conversions


view this post on Zulip Jonathan (Aug 09 2026 at 12:51):

I'm not sure why the following evaluates at compile time

Ok(v) = (0xFF.U32).to_u8_try()

but attempting the following gives a non exhaustive destructuring error

to_u8_clamp = |limit| {
    match limit.to_u8_try() {
        Ok(limit_u8) => {
            Ok(
                |v| {
                    if v < limit v.to_u8_wrap() else limit_u8
                },
            )
        }
        Err(_) => Err(LimitTooBig)
    }
}

f = || {
    Ok(converter) = to_u8_clamp(0xFF.U32)  # <- Error here
    converter(120)
}

to_u8_clamp is a pure function using the same underlying to_u8_try, so I would have thought that the same compile time evaluation and destructuring would be possible.

view this post on Zulip Jonathan (Aug 09 2026 at 13:05):

Just for testing, if limit is set inside the function instead, I get a warning that the value being matched is known at compile time, but I still can't destructure the result like Ok(converter) = .

testing = || {
    limit = 0xFF.U32
    match limit.to_u8_try() {    #  <- Warning: this value is known at compile time
        Ok(limit_u8) => {
            Ok(
                |v| {
                    if v < limit v.to_u8_wrap() else limit_u8
                },
            )
        }
        Err(_) => Err(LimitTooBig)
    }

}

main! = |_| {
    Ok(f) = testing() # <- Error: Non Exhaustive Destructuring
    Ok({})
}

The warning doesn't say explicitly, however, that "the Ok(...) branch will always match". (If that's relevant)

view this post on Zulip Richard Feldman (Aug 09 2026 at 14:43):

this seems like a bug - can you open a GH issue?

view this post on Zulip Jonathan (Aug 10 2026 at 09:46):

Sorry for the delay, yes sure! #10721

view this post on Zulip Jonathan (Aug 10 2026 at 09:56):

Opened #10722 too


Last updated: Aug 12 2026 at 12:35 UTC