Description
Do trait method signatures have to match exactly, or is there some subtyping relationship that is supposed to hold between an impl's methods and the methods of the trait definition itself?
If there is a subtyping relationship, then I would expect the following to compile:
#![crate_type="lib"]
// illustrating subtype relationship: typeof(g) <: typeof(f) ...
fn foo<'a,'b>(ignored: Option<&'a &'b ()>, f: || -> &'a int) { unimplemented!() }
fn bar<'a,'b>(ignored: Option<&'a &'b ()>, g: || -> &'b int) { foo(ignored, g) }
// ... but does that subtype relationship apply to the return types here?
trait T { fn m<'a,'b>(self, ignored: Option<&'a &'b ()>) -> &'a int; }
impl T for () { fn m<'a,'b>(self, ignored: Option<&'a &'b ()>) -> &'b int { unimplemented!() } }
(it currently does not compile; it complains of the mismatch between the lifetime parameters.)
If there is not a subtyping relationship, then I would not expect the following to compile:
#![crate_type="lib"]
trait T<'a> { fn m(&'a self) -> &'a int; }
impl<'ignored> T<'ignored> for () { fn m<'a>(&'a self) -> &'a int { unimplemented!() } }
(it currently does compile.)
Note that the latter case seems sound to me, but the fact that this works in the latter case but does not for the former case just makes me worry about what the rules actually are that we are enforcing with respect to how much an impl
needs to conform with its corresponding trait
.