Michael
Michael

Reputation: 1353

What does the Rust error code E0495 mean?

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

Answers (1)

Peter Hall
Peter Hall

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

Related Questions