error: lifetime bound not satisfied
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
use askama::Template;
use askama_web::WebTemplate;
use async_trait::async_trait;
use axum::Router;
use axum::extract::{Path, Request, State, FromRequestParts};
use axum::response::{IntoResponse, Response};
use axum::routing::get;
use snafu::prelude::*;
#[derive(Clone, Debug)]
pub struct AppState;
impl AppState {
pub async fn context(&self) -> Result<AppStateContext, AppStateError> {
// We simulate a global non-recoverable app error
if Self::random_failure() {
return Err(AppStateError::RandomFail);
}
Ok(AppStateContext {
errors: vec!(),
foo: Self::foo().to_string(),
})
}
pub fn foo() -> &'static str {
"foo"
}
// A runtime failure that affects the application globally (non-recoverable).
pub fn random_failure() -> bool {
rand::random_bool(0.5)
}
// A runtime failure which the route will decide to ignore or not.
pub async fn db_operation() -> Result<(), AppStateError> {
if Self::random_failure() {
Err(AppStateError::DBFail)
} else {
Ok(())
}
}
}
#[derive(Debug)]
pub struct AppStateContext {
pub errors: Vec<AppStateError>,
pub foo: String,
}
#[derive(Debug, Snafu)]
pub enum AppStateError {
#[snafu(display("Connection to the database failed."))]
DBFail,
#[snafu(display("Random global failure."))]
RandomFail,
#[snafu(display("Other error: {source}"))]
Other {
source: Box<dyn snafu::Error + Send + Sync + 'static>
},
}
impl IntoResponse for AppStateError {
fn into_response(self) -> Response {
let view = AppStateErrorView { error: self };
view.into_response()
}
}
/// Helper struct because Snafu and Template have conflicting derives
/// (both implement Display).
///
/// ```askama
/// ERROR:: {{ error }}
/// ```
#[derive(Debug, Template, WebTemplate)]
#[template(ext = "html", in_doc = true)]
pub struct AppStateErrorView {
pub error: AppStateError,
}
#[derive(Debug)]
pub struct AppRouteView<T> {
pub route: T,
pub state: AppStateContext,
}
impl<T: IntoAppRouteView> AppRouteView<T> {
pub async fn new(req: Request, state: AppState) -> Result<impl IntoResponse, AppStateError> {
let context = state.context().await?;
Ok(T::from_app_request(req, state, context).await?)
}
}
#[async_trait]
pub trait IntoAppRouteView {
async fn from_app_request(req: Request, state: AppState, mut context: AppStateContext) -> Result<impl IntoResponse, AppStateError>;
}
#[derive(Debug)]
pub struct IndexRouteContext {
pub id: usize,
}
#[async_trait]
impl IntoAppRouteView for IndexRouteContext {
async fn from_app_request(req: Request, state: AppState, mut context: AppStateContext) -> Result<impl IntoResponse, AppStateError> {
// Simulate an operation that fails without affecting global operations
if rand::random_bool(0.5) {
context.errors.push(AppStateError::DBFail);
}
let (mut parts, body) = req.into_parts();
// This is a route-specific operation that can fail and affects global operations
let Path(id) = Path::<usize>::from_request_parts(&mut parts, &state).await.boxed().context(OtherSnafu)?;
let _req = Request::from_parts(parts, body);
Ok(IndexRouteView {
ctx: AppRouteView {
route: IndexRouteContext {
id,
},
state: context,
}
})
}
}
/// ```askama
/// <div>Hello, user n° {{ ctx.route.id }}!</div>
/// ```
#[derive(Debug, WebTemplate, Template)]
#[template(ext = "html", in_doc = true)]
pub struct IndexRouteView {
ctx: AppRouteView<IndexRouteContext>,
}
// #[axum::debug_handler]
pub async fn index_route(State(app_state): State<AppState>, req: Request) -> Result<impl IntoResponse, AppStateError> {
Ok(AppRouteView::<IndexRouteContext>::new(req, app_state).await?)
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
let app = Router::new()
.route("/{id}", get(index_route))
.with_state(AppState);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
Current output
$ cargo run
Compiling axum-test-askama v0.1.0 (/home/user/Prog/angrynode/axum-test-askama)
error: lifetime bound not satisfied
--> src/main.rs:155:25
|
155 | .route("/{id}", get(index_route))
| ^^^^^^^^^^^^^^^^
|
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
error: could not compile `axum-test-askama` (bin "axum-test-askama") due to 1 previous error
Desired output
???
Rationale and extra context
This problem is similar to #100013, #143971 (etc) but compared with other tickets i found the difference here is i have zero explicit lifetime in my code (before macro expansion) and the rustc error is very mysterious: which lifetime bound is not satisfied? satisfied by what?
Compiling on nightly with -Zhigher-ranked-assumptions works just fine so maybe we don't need to improve diagnostic output on stable if stabilization for this feature is coming soon?
Other cases
Rust Version
rustc 1.89.0 (29483883e 2025-08-04)
binary: rustc
commit-hash: 29483883eed69d5fb4db01964cdf2af4d86e9cb2
commit-date: 2025-08-04
host: x86_64-unknown-linux-gnu
release: 1.89.0
LLVM version: 20.1.7
Anything else?
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the failure with cargo run from the provided src/main.rs, especially the get(index_route) call at line 155. Compare stable rustc 1.89.0 with nightly using -Zhigher-ranked-assumptions, then read the related Rust issues #100013 and #143971. Done means the stable compiler provides a clear diagnostic or correctly accepts this reduced case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100