Calling a Method/Trait of Struct with Const Generic and Specialized Impl

Hi,

I need to implement trait/method (at the moment both seem fine, but I might go with trait in the future depending on some factors) for a struct with const generics.

I will do some custom run-time detection and choose one of the available values for const generic in my struct.

I found two strategies to do this for trait/method impl:

  1. Implement trait/method for each const generic value separately, see the playground link for this means in the code

or

  1. Use const generic and implement different cases with if condition and let the compiler optimize the const if branching.

Method 1 does not work, compiler cannot realize that there are impl for each possible value of const generic (2 in this case const generic is boolean).

But method 2 works fine and seems to optimize the const branching.

I am putting minimal version to reproduce the same problem as playground link for both trait and method cases.

I would appreciate any insight as to why method 1 does not work, but method 2 does.

Trait impl: Rust Playground

Method impl: Rust Playground

The first method doesn't work because the compiler doesn't perform impl-level global exhaustiveness checking. While it may seem obvious here that bool can only ever be true or false, this is much harder or even impossible in the general case. (Wanting specialization-like features is almost always a code smell, anyway.)

Just go with the 2nd strategy and let the optimizer do its work.


Better yet, don't use a const bool at all. Use a regular type and implement something like the strategy pattern, like this:


struct Old;
struct New;

impl Op for Old {
    fn print_op_name()  {
        println!("This is old op!!");
    }
}
impl Op for New {
    fn print_op_name()  {
        println!("This is new op!!");
    }
}

struct OpRunner<Age>(Age);


impl<Age: Op> Op for OpRunner<Age> {
    fn print_op_name()  {
        Age::print_op_name();
    }
}

If you squint, you might not even actually need OpRunner; you could probably do all of this with just Age, Old and New.

1 Like

Thanks for the answer.

In the actual code, I need to use const bool since it used by some other method with const generic (otherwise, I would have to double to code for each explicit version of struct (old and new).

The specialization is required since the code is intended for high-performance code and will be used for certain number of distinct cases.

No, that still doesn't require either const generics or specialization. The pattern demonstrated above can be generalized to any method or trait. Also, if you need a const, you can have associated consts in traits. You can get a const value based on a type.

1 Like