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:
It's quite a bit going on here. In order to explain it, let's look at this even more simplified version of your problem. To avoid hiding things, I also replaced the try!()
with its explicit form.
enum SomeError<'a> {
Something(&'a str),
Other,
}
// ... impls Debug, Display, Error for SomeError ...
fn do_stuff(doc: &u32) -> Result<(), SomeError> { Ok(()) }
fn get_things(doc: &Vec) -> Result<(), Box> {
match do_stuff(&v[0]) { // `try!` expands into this match
Ok(v) => Ok(v),
Err(e) => Err(e.into()),
} // ^^^^^^^^--- #1
}
fn main() {
let _ = get_things(&vec![]);
}
This is the first thing that might be confusing: try!
calls std::convert::From::from(e)
(or equivalent, but shorter: e.into()
). This means that the interesting spot is only the part marked with #1
.
So what is going on there?
Calling into()
means that the Rust compiler has to search for some implementation of Into
for SomeError
. Through the magic impl
indirection, the compiler finds a few implementations that might work out, notably this one:
impl<'a, E: Error + 'a> From for Box
Here we see another key point: the type Box
has a lifetime bound in it. The type in plain English would read something like: "a boxed type that implements the trait Error
and is alive at least for the lifetime 'a
".
And now we look at our function signature and see Result<(), Box
: it doesn't have a lifetime bound in it! Well... we didn't explicitly write one out, but the compiler adds one anyway, because it's the only way to work with such boxed traits. This RFC is about default lifetime bounds that the compilers adds automagically. And for Box
the lifetime bound 'static
is added. Thus the return type explicitly written out is Result<(), Box
.
To make your code compile, add an explicit lifetime to the input parameter and to the output type, like so:
fn get_things<'a>(doc: &'a Vec) -> Result<(), Box> {
...
}
That way you can avoid the 'static
lifetime bound added by default and tell the compiler that the thing in your box only has to life as long as your input parameter.