Reputation: 1353
I'm using Rocket to make a web server and I'm trying to make a wrapper around the Responder
trait so that my route methods can return any struct.
The code below does not compile because of an error about lifetimes that I don't fully understand. The error is not listed in the error index; it skips from E0492
to E0496
.
Since this code uses Rocket, it requires the nightly compiler.
main.rs
#![feature(custom_attribute, proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
extern crate rocket_contrib;
use rocket::{http::Status, response::Responder, Request};
use rocket_contrib::templates::Template;
fn main() {
rocket::Rocket::ignite().mount("/", routes![route]).launch();
}
#[get("/")]
fn route<'a>() -> DynamicResponder<'a> {
DynamicResponder::from(Template::render("template", ()))
}
struct DynamicResponder<'a> {
inner: Box<dyn Responder<'a> + 'a>,
}
impl<'r> DynamicResponder<'r> {
pub fn from<T: 'r>(responder: T) -> DynamicResponder<'r>
where
T: Responder<'r>,
{
DynamicResponder {
inner: Box::new(responder),
}
}
}
impl<'r> Responder<'r> for DynamicResponder<'r> {
fn respond_to<'b>(
self,
request: &'b Request,
) -> Result<rocket::response::Response<'r>, Status> {
self.inner.respond_to(request)
}
}
Cargo.toml
[package]
name = "rocketing_around"
version = "0.1.0"
[dependencies]
rocket = "0.4.0"
[dependencies.rocket_contrib]
version = "0.4.0"
default_features = false
features = [ "handlebars_templates" ]
Compiler message:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'r` due to conflicting requirements
--> src/main.rs:15:5
|
15 | DynamicResponder::from(Template::render("template", ()))
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 14:10...
--> src/main.rs:14:10
|
14 | fn route<'a>() -> DynamicResponder<'a> {
| ^^
= note: ...so that the expression is assignable:
expected DynamicResponder<'a>
found DynamicResponder<'_>
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the types are compatible:
expected rocket::response::Responder<'_>
found rocket::response::Responder<'static>
Upvotes: 3
Views: 1508
Reputation: 58735
What does the Rust error code E0495 mean?
The error code E0495
seems to be a catch-all for a variety of different situations where lifetime requirements can't be reconciled. The message already says that, and there are huge number of ways that you could write code where lifetimes don't match up properly, which is perhaps why it isn't listed with examples in the error index.
Type parameters, including lifetimes, are always determined by the caller. Looking at your particular example, a function signature like this:
fn route<'a>() -> DynamicResponder<'a> { ... }
means that, for any lifetime 'a
chosen by the caller, references inside the returned DynamicResponder<'a>
must be valid. But what could the references inside DynamicResponder<'a>
even be in this situation? They can't be references to variables in the function body because those only live as long as the function. There are no arguments, so the only things that could be referenced by the DynamicResponder<'a>
are things that live outside the function, i.e. statics.
You can fix the error by removing the lifetime variable and setting the lifetime parameter to the only lifetime that makes sense:
fn route() -> DynamicResponder<'static> { ... }
Upvotes: 4