What is a predicate in Rust?

Viewed 1592

When I try to compile this code:

impl<S, V> Storage for Database<S>
where
    S: StoredElement,
    V: VisibleElement,

The compiler complains

error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates
  --> src/main.rs:77:9
   |
77 | impl<S, V> Storage for Database<S>
   |         ^ unconstrained type parameter

I assumed V: VisibleElement is a predicate, but apparently the compiler disagrees.

So, in Rust, what exactly is a predicate?

1 Answers

V: VisibleElement is a predicate in this context. The problem is that the predicate doesn't constrain the types sufficiently for V to be relevant in any way.

The compiler sees V and also V: VisibleElement, and then it just throws them away because they have no impact on:

  • which trait you are implementing (the impl trait)
  • or the type for which you are implementing the trait (self type)
  • or any of the constraints on either of those (the predicates or bounds).

For example, if the predicate included a relationship between V and S then that would make sense, because it would add information about which implementations are being defined here. For example, that could be something like this:

impl<S, V> Storage for Database<S>
where
    S: StoredElement<ChildType = V>,
    V: VisibleElement,

I've made up the types here, as I don't know where the actual types are from. This would be a meaningful usage of V because it is constraining S to not only StoredElement but to StoredElements whose associated ChildType implements VisibleElement. This will only define the implementation of Storage for Database where that condition (predicate) is met.

The compiler is complaining because you've added a parameter that has no impact whatsoever and that is most likely to be a mistake on your part.

Related