I've got the following code (doesn't make much sense, just a minimised test case):
extern crate rustc_serialize;
use rustc_serialize::json::Json;
use std::error::Error;
struct SomeStruct;
#[derive(Debug)]
enum SomeError<'a> {
Something(&'a str),
Other,
}
fn do_stuff(doc: &Json) -> Result<SomeStruct, SomeError> {
Ok(SomeStruct)
}
fn get_things(doc: &Vec<Json>) -> Result<SomeStruct, Box<Error>> {
let res = try!(doc.get(0).ok_or(SomeError::Other));
Ok(try!(do_stuff(&res))) //// line 20
}
fn main() {
let _ = get_things(&vec!(Json::Null));
}
impl<'a> std::fmt::Display for SomeError<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(f, "blah")
}
}
impl<'a> Error for SomeError<'a> {
fn description(&self) -> &str { "blah" }
}
This fails with a type mismatch at line 20: expected std::result::Result<SomeStruct, Box<std::error::Error + 'static>>, found std::result::Result<SomeStruct, Box<std::error::Error>>
I don't understand where did the 'static
lifetime requirement come from suddenly. If I change the enum to use Something(&'static str)
it works just fine, but why can't I use a less restrictive value here?
The error mentiones that doc
is the borrowed content that the error cannot outlive... but there doesn't seem to be any relation between those two types.
Full error:
error: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements [E0495]
--> src/main.rs:19:24
19 |> let res = try!(doc.get(0).ok_or(SomeError::Other));
|> ^^^
src/main.rs:19:15: 19:55: note: in this expansion of try! (defined in <std macros>)
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 18:65...
--> src/main.rs:18:66
18 |> fn get_things(doc: &Vec<Json>) -> Result<SomeStruct, Box<Error>> {
|> ^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:19:20
19 |> let res = try!(doc.get(0).ok_or(SomeError::Other));
|> ^^^
src/main.rs:19:15: 19:55: note: in this expansion of try! (defined in <std macros>)
note: but, the lifetime must be valid for the static lifetime...
note: ...so that types are compatible (expected std::result::Result<SomeStruct, Box<std::error::Error + 'static>>, found std::result::Result<SomeStruct, Box<std::error::Error>>)
--> <std macros>:5:8
5 |> return $ crate :: result :: Result :: Err (
|> ^
src/main.rs:20:8: 20:28: note: in this expansion of try! (defined in <std macros>)