Skip to content

"higher-ranked lifetime error" on rust 1.90 #147285

@dspyz-matician

Description

@dspyz-matician

This code compiles on 1.89 and then fails to compile with "higher-ranked lifetime error" starting in 1.90

I tried this code:

use hyper_util::rt::TokioIo; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_rustls::{ TlsConnector, rustls::pki_types::{IpAddr, ServerName}, }; use tonic::transport::{Endpoint, Uri}; pub trait AsyncStream: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static {} impl<T: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static> AsyncStream for T {} type BoxStream = Box<dyn AsyncStream>; fn main() { println!("Hello, world!"); } fn bad_fn( connector: TlsConnector, endpoint: Endpoint, ) -> impl Future<Output = Result<tonic::transport::Channel, tonic::transport::Error>> + Send { async move { let rpc_channel = endpoint .connect_with_connector(tower::service_fn(move |_: Uri| { let connector = connector.clone(); let box_stream = get_box_stream(); async move { connector .connect( // This Address does not matter. I am using an ip address as opposed to a hostname to avoid // an attempt at using SNI. ServerName::IpAddress(IpAddr::V4("127.0.0.1".try_into().unwrap())), box_stream, ) .await .map(|stream| TokioIo::new(Box::new(stream) as BoxStream)) } })) .await?; Ok(rpc_channel) } } fn get_box_stream() -> BoxStream { todo!() }

I expected to see this happen: Anything which compiled before the upgrade I would expect to compile after

Instead, this happened: It doesn't

Meta

rustc --version --verbose:

rustc 1.90.0 (1159e78c4 2025-09-14) binary: rustc commit-hash: 1159e78c4747b02ef996e55082b704c09b970588 commit-date: 2025-09-14 host: x86_64-unknown-linux-gnu release: 1.90.0 LLVM version: 20.1.8 
Backtrace

dspyz@davids-desktop:~/mwe$ RUST_BACKTRACE=1 cargo check Checking mwe v0.1.0 (/home/dspyz/mwe) error: higher-ranked lifetime error --> src/main.rs:21:5 | 21 | / async move { 22 | | let rpc_channel = endpoint 23 | | .connect_with_connector(tower::service_fn(move |_: Uri| { 24 | | let connector = connector.clone(); ... | 39 | | Ok(rpc_channel) 40 | | } | |_____^ error: could not compile `mwe` (bin "mwe") due to 1 previous error 

git repo here

It gets even weirder. If I change it to a trait method, I get:

the type `TokioIo<Box<dyn AsyncStream>>` does not fulfill the required lifetime 

TokioIo<Box<dyn AsyncStream>> is a fully static type so it should fulfill all lifetimes.

use hyper_util::rt::TokioIo; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_rustls::{ TlsConnector, rustls::pki_types::{IpAddr, ServerName}, }; use tonic::transport::{Endpoint, Uri}; pub trait AsyncStream: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static {} impl<T: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static> AsyncStream for T {} type BoxStream = Box<dyn AsyncStream>; fn main() { println!("Hello, world!"); } trait BadTrait { fn bad_fn( connector: TlsConnector, endpoint: Endpoint, ) -> impl Future<Output = Result<tonic::transport::Channel, tonic::transport::Error>> + Send; } impl BadTrait for () { async fn bad_fn( connector: TlsConnector, endpoint: Endpoint, ) -> Result<tonic::transport::Channel, tonic::transport::Error> { let rpc_channel = endpoint .connect_with_connector(tower::service_fn(move |_: Uri| { let connector = connector.clone(); let box_stream = get_box_stream(); async move { connector .connect( // This Address does not matter. I am using an ip address as opposed to a hostname to avoid // an attempt at using SNI. ServerName::IpAddress(IpAddr::V4("127.0.0.1".try_into().unwrap())), box_stream, ) .await .map(|stream| TokioIo::new(Box::new(stream) as BoxStream)) } })) .await?; Ok(rpc_channel) } } fn get_box_stream() -> BoxStream { todo!() }
error[E0477]: the type `TokioIo<Box<dyn AsyncStream>>` does not fulfill the required lifetime --> src/main.rs:25:5 | 25 | / async fn bad_fn( 26 | | connector: TlsConnector, 27 | | endpoint: Endpoint, 28 | | ) -> Result<tonic::transport::Channel, tonic::transport::Error> { | |___________________________________________________________________^ | note: type must satisfy the static lifetime as required by this binding --> src/main.rs:21:93 | 21 | ) -> impl Future<Output = Result<tonic::transport::Channel, tonic::transport::Error>> + Send; | ^^^^ error[E0477]: the type `{async block@src/main.rs:33:17: 33:27}` does not fulfill the required lifetime --> src/main.rs:25:5 | 25 | / async fn bad_fn( 26 | | connector: TlsConnector, 27 | | endpoint: Endpoint, 28 | | ) -> Result<tonic::transport::Channel, tonic::transport::Error> { | |___________________________________________________________________^ | note: type must satisfy the static lifetime as required by this binding --> src/main.rs:21:93 | 21 | ) -> impl Future<Output = Result<tonic::transport::Channel, tonic::transport::Error>> + Send; | ^^^^ 

Metadata

Metadata

Labels

C-bugCategory: This is a bug.P-highHigh priorityS-has-bisectionStatus: A bisection has been found for this issueS-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issueT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions