trait Foo {
const fn bar(arg: Arg) -> Ret;
}почему? потому, оставили невозможным что бы дизайнить взаимодействие конста и трейтов в спокойствии еще несколько лет.
Если бы без
Arg - я бы просто сделал const BAR: Ret.Если что
const BAR<const ARG: Arg>; Тоже нельзя, но хотя бы в найтли можно.Пробовал сделать функцию не
const, но писать её, как если бы она была const. Надеялся, что соптимизируется.До некоторой глубины действительно оптимизировалось.
В итоге пришел вот к такой форме "конст-функции-на-стейбле"
trait Foo {
type Bar<const ARG: Arg>: RetType;
}
trait RetType {
const VALUE: Ret;
}
impl Foo for FooImpl {
type Bar<const ARG: Arg> = FooBar<ARG>;
}
struct FooBar<const ARG: Arg>;
impl RetType for FooBar<const ARG: Arg> {
const VALUE: Ret = {
// faked const fn body.
};
}Это ужасно выглядит? Да.
Это гарантирует, что в результате компиляции на месте
FooImpl::Bar::<ARG>::VALUE будет константа, а не вызов функции? Тоже да.