rustc accepts impls that has different type signatures from trait decls in lifetime parameters of the type

50bdc33
Opened by κeen at 2024-05-14 03:02:29

I thought this code was invalid because 1. it had a redundant lifetime parameter and 2. it had different types from the trait decl in the types of the argument and the return value.

trait Foo<T> {
    fn foo(&self, t: T) -> T;
}

impl<'a> Foo<Option<&'a str>> for () {
    fn foo<'b>(&self, t: Option<&'b str>) -> Option<&'b str> {
        t
    }
}

but the compiler (both stable (1.22.1) and nightly (9fe7aa353 2017-12-11)) accepts this code. Is this indended or a bug?

FYI: it seems compiler treat the signature method foo as the one of Foo (or, perhaps unifying 'b to 'a?) so it doesn't cause unsafe states like dangling pointer.

fn main() {
    let s = "String".to_string();
    {
        let o = Some(s.as_ref());
        let _ = <() as Foo<Option<&'static str>>>::foo(&(), Some("static"));
        // error
        let _ = <() as Foo<Option<&'static str>>>::foo(&(), o);
        // error
        let _: Option<&'static str> = ().foo(o);
    }

}
  1. Note for future readers: 'b is late-bound here. Forcing it to be early-bound (e.g., by adding where 'b:,) makes rustc reject the trait impl.

    León Orell Valerian Liehr at 2024-05-14 03:02:23