This code (derived from a more complex example) compiles [playground]:
fn func1<'a>(s: &'a str) where 'static: 'a { println!("{s}"); }
fn func2<'a>(s: &'a str) { func1(s) }
trait MyTrait {
fn func<'a>(s: &'a str) where 'static: 'a;
}
impl MyTrait for () {
fn func<'a>(s: &'a str) where 'static: 'a { println!("{s}"); }
}
fn main() {
func2("hello");
<()>::func("world");
}
but this one does not [playground]:
fn func1<'a>(s: &'a str) where 'static: 'a { println!("{s}"); }
fn func2<'a>(s: &'a str) { func1(s) }
trait MyTrait {
fn func<'a>(s: &'a str) where 'static: 'a;
}
impl MyTrait for () {
fn func<'a>(s: &'a str) { println!("{s}"); }
}
fn main() {
func2("hello");
<()>::func("world");
}
As func1 and func2 show, constraint 'static: 'a appears to be a blank constraint.
So why is it necessary when implementing the trait?
Further comment on the question: if this is a simple signature problem relating to where clauses, why does this example compile? [playground]
use std::fmt::Debug;
trait MyTrait<T> {
fn func<'a>(s: &'a str) where T: 'a + Debug;
}
impl MyTrait<f64> for () {
fn func<'a>(s: &'a str) where 'static: 'a { println!("{s}"); }
}
trait MyTrait2<T> {
fn func2(s: &str) where T: Debug;
}
impl MyTrait2<f64> for () {
fn func2(s: &str) { println!("{s}"); }
}
fn main() {
<()>::func("hello");
<()>::func2("world");
}
and not this one: [playground]
use std::fmt::Debug;
trait MyTrait<T> {
fn func<'a>(s: &'a str) where T: 'a + Debug;
}
impl MyTrait<f64> for () {
fn func<'a>(s: &'a str) where f64: Debug { println!("{s}"); }
}
fn main() {
<()>::func("hello world");
}
whereis part of the signature, you must match the signature exatly.wherein the implementation.whereclause because there are no unbound generic parameters:f64is a known type and the compiler knows thatf64: Debugso all is fine. In the non-working cases,'ais unknown so the constraint must be specified (the compiler never checks if a constraint is valid for all possible values, it only checks if the constraint is valid for the known values).