Misleading error when a trait method implementation has explicit lifetime parameters but the trait signature does not.
Consider this example (playground):
use std::vec::Vec;
use std::option::Option;
trait MyTrait {
fn bar(&self, vec: &Vec<u32>) -> Option<&u32>;
}
struct Foo;
impl MyTrait for Foo {
fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> {
vec.get(0)
}
}
The error message is:
rustc 1.18.0-nightly (7627e3d31 2017-04-16)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements
--> <anon>:11:5
|
11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> {
| _____^ starting here...
12 | | vec.get(0)
13 | | }
| |_____^ ...ending here
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 11:60...
--> <anon>:11:61
|
11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> {
| _____________________________________________________________^ starting here...
12 | | vec.get(0)
13 | | }
| |_____^ ...ending here
note: ...so that method type is compatible with trait (expected fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>, found fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>)
--> <anon>:11:5
|
11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> {
| _____^ starting here...
12 | | vec.get(0)
13 | | }
| |_____^ ...ending here
note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the body at 11:60...
--> <anon>:11:61
|
11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> {
| _____________________________________________________________^ starting here...
12 | | vec.get(0)
13 | | }
| |_____^ ...ending here
note: ...so that method type is compatible with trait (expected fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>, found fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>)
--> <anon>:11:5
|
11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> {
| _____^ starting here...
12 | | vec.get(0)
13 | | }
| |_____^ ...ending here
error: aborting due to previous error
All of the text of the error is focussed on the body of the function, even though there are no lifetime problems in the body with respect to the signature of the surrounding function. The actual error is that the signatures of the trait method and its implementation do not match.
Current output is still mistifying:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements --> src/main.rs:11:5 | 11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 11:5... --> src/main.rs:11:5 | 11 | / fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> { 12 | | vec.get(0) 13 | | } | |_____^ note: ...but the lifetime must also be valid for the anonymous lifetime #1 defined on the method body at 11:5... --> src/main.rs:11:5 | 11 | / fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> { 12 | | vec.get(0) 13 | | } | |_____^ = note: ...so that the method type is compatible with trait: expected fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32> found fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>Esteban Kuber at 2018-03-15 04:12:46
The error from this Stack Overflow question might be related: https://stackoverflow.com/questions/49844281/why-do-i-get-missing-lifetime-in-this-pice-of-code
OP is seeing an error with lifetimes but actually he has just got the trait signature wrong.
Peter Hall at 2018-04-15 17:06:14
That OP has edited their question to no longer be meaningful to this discussion. This is the relevant revision:
use std::ops::Index; enum J_List<T> { Cons(T, Box<J_List<T>>), Nil, } struct List<T> { value: J_List<T>, } impl<T> Index<usize> for List<T> { type Output = T; fn index(self, x: usize) -> &T { unimplemented!(); } }Jake Goulding at 2018-04-15 20:32:21
Triage: no change for the OP. For the case brought up in StackOverflow, the current output is
error[E0106]: missing lifetime specifier --> src/lib.rs:15:33 | 15 | fn index(self, x: usize) -> &T { | ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static` | = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the argumentsand if you follow the compiler advice you get
error[E0053]: method `index` has an incompatible type for trait --> src/lib.rs:15:5 | 15 | fn index(self, x: usize) -> &'static T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &List<T>, found struct `List` | = note: expected type `fn(&List<T>, usize) -> &T` found type `fn(List<T>, usize) -> &'static T`which nudges you in the right direction:
impl<T> Index<usize> for List<T> { type Output = T; fn index(&self, x: usize) -> &T { unimplemented!(); } }The first message already mentions "this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments", which could use a rephrase, but tells you what's wrong here.
Esteban Kuber at 2019-09-23 05:14:34
The current output still fails to differentiate the lifetimes involved:
error: `impl` item signature doesn't match `trait` item signature --> src/main.rs:11:5 | 5 | fn bar(&self, vec: &Vec<u32>) -> Option<&u32>; | ---------------------------------------------- expected fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32> ... 11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32> | = note: expected `fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>` found `fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>`Esteban Kuber at 2019-11-14 19:21:22
-
error: `impl` item signature doesn't match `trait` item signature --> src/main.rs:11:5 | 5 | fn bar(&self, vec: &Vec<u32>) -> Option<&u32>; | ---------------------------------------------- expected `fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>` ... 11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>` | = note: expected `fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>` found `fn(&Foo, &std::vec::Vec<u32>) -> std::option::Option<&u32>` = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its outputEsteban Kuber at 2020-06-10 21:16:28
Current output:
error: `impl` item signature doesn't match `trait` item signature --> src/main.rs:11:5 | 5 | fn bar(&self, vec: &Vec<u32>) -> Option<&u32>; | ---------------------------------------------- expected `fn(&'1 Foo, &'2 Vec<u32>) -> Option<&'1 u32>` ... 11 | fn bar<'a>(&self, vec: &'a Vec<u32>) -> Option<&'a u32> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Foo, &'2 Vec<u32>) -> Option<&'2 u32>` | = note: expected `fn(&'1 Foo, &'2 Vec<u32>) -> Option<&'1 u32>` found `fn(&'1 Foo, &'2 Vec<u32>) -> Option<&'2 u32>` = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its outputEsteban Kuber at 2022-06-08 22:02:44