Check if a trait is implemented or not

How to check if a struct implement some trait and calculate boolean result.

For example:

struct Foo;
struct Bar;

trait Qux {}
impl Qux for Foo {}
const fn is_qux<T>() -> bool { ... }

assert!(is_qux::<Foo>());
assert_ne!(is_qux::<Bar>());
1 Like

This is not currently possible; specialization can fix it though. However, it's a pretty weird requirement – one doesn't usually check whether or not a trait is implemented, that's not how you design interfaces. What is the higher-level goal you are trying to achieve?

I had a similar wish but then decided to not use any feature gates.

What is the higher-level goal you are trying to achieve?

Well, Run some code If a trait 'X' is implemented, Otherwise run else block.

In that case, just implement a method of that trait with different concrete behaviors for different types. Incidentally, that's exactly the idiomatic way to use traits. You shouldn't be checking types from the outside – it violates encapsulation and hurts modularity.

4 Likes

I can't, This is a auto traits

Which one, specifically?

Sorry, I didn't understand the question,

But I declare a auto trait, let's say,
auto trait Qux {}

and Qux doesn't implement Bar,

impl !Qux for Bar {}

Now I need to check if there any Bar present or not, for example:

fn test<T: Display>(val: T) {
    if is_qux::<T> {
        println!("Found It!");
    } else {
        println!("{val}, Doesn't contain any qux");
    }
}
struct Foo<T>(T);
test(Foo(Bar));
test("Just String");

I was asking, which built-in auto trait it is, so that I can offer more specific advice about it. If you are using nightly to define your own auto trait, then we are back at square one – you should just not define an auto trait and implement a regular trait differently for different types instead.

This is not really sanctioned, but there's a way to leverage std's internal Copy/Clone specialization:

I found a hack (but this is not generic), which requited code gen (macro) in order to work,

Macro definition is like this:

Actually There is a reason for using auto trait, And that is, If any data type does in implement a specific (in the case, it's Qux) trait, Then the whole struct is not Qux like

You can think it's something like Send, Sync, Unpin etc...

If you are using a nightly version (since you are using auto trait feature), then use the feature "specialization" (It is suggested to use to min_specialization avoid most of the pitfalls). If you are using a stable version, you can't do it any way.

1 Like

Note that this doesn't work in generic contexts. If you have an unknown generic T without bounds on it, the macro will always pick false. If you're going to use it with concrete types only then it's good enough.