I have this code
struct Min<T, const N: usize>(T, PhantomData<usize>);
But N isn't always a usize. I tried passing N: T to make N could accept any numeric type like this, but it didn't work
struct Min<T, const N: T>(T, PhantomData<T>);
Is there a way to do this?
edddd
February 19, 2026, 5:17pm
2
struct Min<U, T : trait_that_implements_nemeric>(U, PhantomData<T>);
your code works, but if you don't use N const, it is better use a type instead
kpreid
February 19, 2026, 5:55pm
3
The feature you are looking for is known as generic_const_parameter_types . It is desired, but not implemented at all, nor even fully designed, yet.
prootia
February 20, 2026, 1:43am
4
This isn't really a full solution, but what you want can perhaps be got through a trait?
trait MinConst
{
type ConstType: Num; // from the `num` crate perhaps
const CONST_VALUE: <Self as MinConst>::ConstType;
}
struct Min<T: Num, U: MinConst<ConstType = T> + ?Sized>(T, PhantomData<U>);
Note how only const generics can become const generics and array size/repeat arguments so this probably doesn't solve your problem.
Thanks everyone for the answers. Everything is running smoothly now. However, I’m still looking for a way to achieve the same effect as const N: T to avoid the runtime .into() conversion seen in this code
use std::marker::PhantomData;
trait Validator<T> {
fn validate(val: &T) -> Result<(), &'static str>;
}
struct Validated<T, V: Validator<T>>(T, PhantomData<V>);
impl<T, V: Validator<T>> Validated<T, V> {
fn new(val: T) -> Result<Self, &'static str> {
V::validate(&val)?;
Ok(Self(val, PhantomData))
}
fn get(&self) -> &T {
&self.0
}
fn take(self) -> T {
self.0
}
}
struct Min<const N: i128>;
impl<T, const N: i128> Validator<T> for Min<N>
where T: PartialOrd + Copy + Into<i128> {
fn validate(val: &T) -> Result<(), &'static str> {
if (*val).into() >= N {
return Ok(());
}
Err("Value too small")
}
}
struct Tes {
val: Validated<i32, Min<10>>
}
fn main() -> Result<(), &'static str> {
let tes = Tes {
val: Validated::new(20)?
};
println!("{}", tes.val.take());
Ok(())
}
Does anyone know how to do that?
Hey, I found this way. Which one is better?
use std::marker::PhantomData;
trait Validator<T> {
fn validate(val: &T) -> Result<(), &'static str>;
}
struct Validated<T, V: Validator<T>>(T, PhantomData<V>);
impl<T, V: Validator<T>> Validated<T, V> {
fn new(val: T) -> Result<Self, &'static str> {
V::validate(&val)?;
Ok(Self(val, PhantomData))
}
fn get(&self) -> &T {
&self.0
}
fn take(self) -> T {
self.0
}
}
trait Num<T> {
const val: T;
}
struct Min<N>(PhantomData<N>);
impl<T, N> Validator<T> for Min<N>
where
T: PartialOrd + Copy,
N: Num<T>
{
fn validate(val: &T) -> Result<(), &'static str> {
if *val >= N::val {
return Ok(());
}
Err("Value too small")
}
}
struct Tes {
val: Validated<i32, Min<Numm>>
}
struct Numm;
impl Num<i32> for Numm {
const val: i32 = 10;
}
fn main() -> Result<(), &'static str> {
let tes = Tes {
val: Validated::new(20)?
};
println!("{}", tes.val.take());
Ok(())
}