Trait bounds could include what they imply

⚓ Rust    📅 2025-08-15    👤 surdeus    👁️ 2      

surdeus

I wanted to write a simple generic function to check if a value is zero. I had an idea - whatever cannot be converted to NonZero is zero. After a long struggle with the compiler, the code compiled, but it's nighly-only and the compiler still warns me about using an internal feature:

#![feature(nonzero_internals)]

use std::num::NonZero;
use std::num::ZeroablePrimitive;

fn is_zero<T>(value: T) -> bool
where
    T: TryInto<NonZero<T>> + ZeroablePrimitive,
{
    let new_value = TryInto::<NonZero<T>>::try_into(value);
    return new_value.is_err();
}

Try removing + ZeroablePrimitive, and the compiler spews a whole page of warnings. NonZero<T> is only implemented for T: ZeroablePrimitive.

I believe trait bounds could be smarter. If trait bounds imply other trait bounds, the latter should be added implicitly.

In this case, if NonZero<T> is used in trait bounds, it implies T: ZeroablePrimitive, so why should I write it explicitly?

3 posts - 3 participants

Read full topic

🏷️ Rust_feed