How to create a const Trait

I would like to know how to create a const trait where any use of this trait must be implemented by a true constant value

Values don't implement traits; types do. Are you by chance trying to constrain a generic function to primitive types?

Trait definition

Trait ConstGet<const T>

This is what I thought creating a const Trait would look like

Const generics are stable (though still limited/evolving).

trait WithConstParameter<const N: usize> {
    fn foo(arr: [String; N]) -> [i128; N];
}

Const implementations of traits are not yet stable.

1 Like

is this appropriate?

/// A trait for querying a single constant value from a type.
///
/// It is required that the value is constant.
pub trait ConstGet<const T: usize> {
	/// Return the current constant value.
	fn get_const() -> T;
}

impl<const T: Default> ConstGet<T> for () {
	fn get_const() -> T {
		T::default()
	}
}

No, there are a lot of disconnects here. Let's start with:

pub trait ConstGet<const T: usize> {
	/// Return the current constant value.
	fn get_const() -> T;
}

Note that T is a constant value, and it's always a usize. That's what const T: usize means. But functions return types, not values. So this doesn't make sense. The comment says you want to associate implementers of the trait with a constant value. And the type ascription says that value is of type usize. That would be something like this:

// Associate every type that implements this trait with a singular,
// constant `usize` value
pub trait HasConst {
    const USIZE: usize;
}

Next, in the implementation, you wrote:

impl<const T: Default> ConstGet<T> for () {
	fn get_const() -> T {
		T::default()
	}
}

But when you have a generic <const T: Whatever>, Whatever must be a concrete, statically known type, not a trait bound. And again, const implementations of traits aren't stable, so you can't utilize a trait in a const context. In particular, the output of Default::default() might not be const and cannot yet be used in a const context. Also, trait methods cannot be const either.

You would implement HasConst as I wrote it above something like this:

// `()` is associated with constant `usize` value `0`
impl HasConst for () {
    const USIZE: usize = 0;
}

But I'm getting the impression you want something both generic and const. I suspect it's not possible, but I still don't have an understanding of what you're actually trying to achieve, so it's hard to be sure.

what i'm trying to achieve

Maybe something like

trait ConstGet<T> {
    const VALUE: T;
}

trait Get<T> {
    fn get() -> T;
}

impl<T, U> Get<T> for U where U: ConstGet<T> {
    fn get() -> T {
        Self::VALUE
    }
}

Or maybe they want ConstGet<T> to have the same signature as Get<T> and you'll need one more layer of indirection.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.