Purpose of where clause when implementing trait for concrete type
⚓ Rust 📅 2026-01-26 👤 surdeus 👁️ 1What is the purpose of a where clause in a trait implementation for a concrete type?
While re-reading the book “Rust for Rustaceans” by @jonhoo, I stumbled across listing 2-6 that demonstrates “an excessively generic implementation of Debug for any iterable collection”. As given in the book, the listing reads
impl Debug for AnyIterable
where for<'a> &'a Self: IntoIterator,
for<'a> <&'a Self as IntoIterator>::Item: Debug {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
f.debug_list().entries(self).finish()
}}
The book says:
You could copy-paste this implementation for pretty much any collection type and it would “just work.” Of course, you may want a smarter debug implementation, but this illustrates the power of trait bounds quite well.
I believed to have understood that trait bounds are used in generic programming to specify the required capacities of a generic type. But in the above example everything is concrete - how would this serve as a demonstration of the power of trait bounds?
Here is a complete program that includes the above snippet, applied to SomeIterable. And, sure enough, it compiles with the where clause commented out:
struct SomeIterable(Vec<String>);
impl<'a> IntoIterator for &'a SomeIterable {
type Item = &'a String;
type IntoIter = std::slice::Iter<'a, String>;
fn into_iter(self) -> Self::IntoIter {
self.0.as_slice().into_iter()
}
}
use std::fmt::{Debug, Error, Formatter};
impl Debug for SomeIterable
// where
// for<'a> &'a Self: IntoIterator,
// for<'a> <&'a Self as IntoIterator>::Item: Debug,
{
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
f.debug_list().entries(self).finish()
}
}
fn main() {
let v = vec![String::from("hello"), String::from("world")];
let v = SomeIterable(v);
dbg!(&v);
}
I must be missing something obvious here, so I hesitated to bother this friendly forum. But unfortunately, I was not able find any discussion of this topic – neither here, nor elsewhere on the web, nor in books that I have.
Is the purpose only to serve as a form of “static typing for a template”, i.e. to provide clearer error messages when the snippet is used for some type in the wild that does not qualify?
6 posts - 4 participants
🏷️ Rust_feed