Mismatched lifetime in trait function declaration is not detected
db5408f
Opened by Mike Hommey at
Consider the following code:
pub trait FromStr<'a>: Sized {
type Err;
fn from_str(s: &'a str) -> Result<Self, Self::Err>;
}
struct Foo<'a>(&'a str);
impl<'a> FromStr<'a> for Foo<'a> {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Foo(s))
}
}
The compiler errors out failing to infer an appropriate lifetime:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/main.rs:11:12
|
11 | Ok(Foo(s))
| ^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 10:5...
--> src/main.rs:10:5
|
10 | / fn from_str(s: &str) -> Result<Self, Self::Err> {
11 | | Ok(Foo(s))
12 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:11:16
|
11 | Ok(Foo(s))
| ^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 8:1...
--> src/main.rs:8:1
|
8 | impl<'a> FromStr<'a> for Foo<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...so that the expression is assignable:
expected std::result::Result<Foo<'a>, _>
found std::result::Result<Foo<'_>, _>
But the most immediate error is that the declaration of from_str doesn't match the trait definition, missing the lifetime bound on &str to match the lifetime associated with the trait.
Current output:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements --> src/lib.rs:11:12 | 11 | Ok(Foo(s)) | ^^^ | note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 10:5... --> src/lib.rs:10:5 | 10 | / fn from_str(s: &str) -> Result<Self, Self::Err> { 11 | | Ok(Foo(s)) 12 | | } | |_____^ note: ...so that reference does not outlive borrowed content --> src/lib.rs:11:16 | 11 | Ok(Foo(s)) | ^ note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 8:6... --> src/lib.rs:8:6 | 8 | impl<'a> FromStr<'a> for Foo<'a> { | ^^ note: ...so that the expression is assignable --> src/lib.rs:11:9 | 11 | Ok(Foo(s)) | ^^^^^^^^^^ = note: expected `std::result::Result<Foo<'a>, _>` found `std::result::Result<Foo<'_>, _>`Output with nll enabled:
error: lifetime may not live long enough --> src/lib.rs:12:9 | 9 | impl<'a> FromStr<'a> for Foo<'a> { | -- lifetime `'a` defined here 10 | type Err = (); 11 | fn from_str(s: &str) -> Result<Self, Self::Err> { | - let's call the lifetime of this reference `'1` 12 | Ok(Foo(s)) | ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a`Esteban Kuber at 2020-02-12 20:28:12
Current output is the nll one above. Ideally we'd suggest using
&'a strinstead of&str, but the error already gives enough information to deal with the problem.Esteban Kuber at 2023-08-03 16:51:18