Hidden type caputures lifetime smaller than function body

I'm having an error I can't understand and cannot precisely locate in the code.

Rustc points the following error ito the sabiah_server return value (line 60):

hidden type for `impl Trait` captures lifetime that does not appear in bounds

note: hidden type `impl std::future::Future` captures lifetime smaller than the function body rustc(E0700)

Can someone explain me it better? If I understand it I shall try to contribute to this issue about a better presentation of the problem.

use crate::lib::SabiahError;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server, StatusCode};
use serde::Deserialize;
use serde_json;
use std::convert::Infallible;
use std::net::{IpAddr, SocketAddr};

mod suggest;
mod tests;

pub const DEFAULT_HOST: &str = "0.0.0.0";
pub const DEFAULT_PORT: &str = "1533";

fn make_response(s: StatusCode, body: Option<Body>) -> Response<Body> {
    let body: Body = match body {
        Some(data) => data,
        None => s.canonical_reason().unwrap().into(),
    };
    Response::builder().status(s).body(body).unwrap()
}

/// Makes up a BAD_REQUEST response for errors during data ingestion.
fn ingest_err(err: SabiahError) -> Response<Body> {
    make_response(StatusCode::BAD_REQUEST, Some(Body::from(err.to_string())))
}

/// Common data ingestion routine. Returns struct after data bind or, if
/// validation/deserialization fails, a response good to be sent.
async fn ingest<T: for<'de> Deserialize<'de>>(data: Request<Body>) -> Result<T, Response<Body>> {
    match hyper::body::to_bytes(data).await {
        Err(err) => Err(ingest_err(err.into())),
        Ok(bin_data) => match serde_json::from_slice(bin_data.as_ref()) {
            Err(err) => Err(ingest_err(err.into())),
            Ok(params) => Ok(params),
        },
    }
}

/// offer hyper services for Sabiah endpoints
async fn services(musilibs: &[String], req: Request<Body>) -> Result<Response<Body>, Infallible> {
    match (req.method(), req.uri().path()) {
        (&Method::GET, "/health") => Ok(Response::new(Body::from("OK (under construction)"))),
        (&Method::POST, "/suggestion") => Ok(suggest::suggest(musilibs, ingest(req).await).await),
        _ => Ok(make_response(StatusCode::NOT_FOUND, None)),
    }
}

async fn signals() {
    tokio::signal::ctrl_c()
        .await
        .expect("failed to install http server signal handlers");
    log::info!("✓ interrupt signal received")
}

pub async fn sabiah_server<'a>(
    host: &str,
    port: &str,
    musilibs: &'static [String],
) -> Result<(), SabiahError> {
    let make_svc = make_service_fn(move |_conn| async move {
        Ok::<_, Infallible>(service_fn(move |req| async move {
            services(musilibs, req).await
        }))
    });
    let ip: IpAddr = host.parse().expect("Sabiah server ip invalid");
    let port: u16 = port.parse().expect("Sabiah server port invalid");
    let addr = SocketAddr::from((ip, port)).into();
    let server = Server::try_bind(&addr)?.serve(make_svc);
    log::info!(
        "✓ server listening at http://{}:{} (use CTRL-C to interrupt)",
        ip,
        port
    );
    server
        .with_graceful_shutdown(signals())
        .await
        .map_err(|e| e.into())
}

I didn't look at your code specifically, but you can read a detailed explanation of E0700 (in the context of async, even) here. And see also the fix-hidden-lifetime-bug crate.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.