Lifetime Bounds

Hi,

I am unsure what the correct title would be for this. This question is in reference to Unexpected higher-ranked lifetime error in GAT usage · Issue #100013 · rust-lang/rust · GitHub.

I encountered this today and would like to understand more about why / how this occurs to gain a better understanding / improve my knowledge.

here is some code that triggers the above issue when <'a> is added.

// main fn

// ! this triggers the error "lifetime bound not satisfied"
let _ = run(service_fn(|event: Request| {
    let span = tracing::info_span!("event_handler");
    
    let fut = async move {
      
      let (d, s) = client_setup().await;
      
      let resp = handler::handle_event(event, d, s).await?;

      Ok::<Response<String>, Error>(resp)
    };
    fut.instrument(span)
  })).await?;

in the handler doing something like:

async fn handler(
  event: Request,
  client: Client,
  client2: Client2,
) -> Result<(), Error> {
  
  // example as a generic function fn<T>
  process_event(event, client, client2).await?;

}

and the generic function being declared like:

async fn process_event<T: ProcessableEvent>(
  event: T,
  client: Client,
  client2: Client,
) -> Result<(), ProcessError> {
  
  let ctx = { client, client2 };

  event.process(ctx).await?;

  Ok(())
}

the trait declaration:

pub trait ProcessableEvent {
  fn process<'a>(
    &self,
    context: ProcessableEventContext
  ) -> impl std::future::Future<Output = Result<(), ProcessError>> + send;
}

if this is implemented on any struct such as something like this:

// impl declaration

impl ProcessableEvent for InventoryChangeEventMessage {
  // ! removing the <'a> removes the error in the main
  async fn process<'a>(&self, ctx: ProcessableEventContext) -> Result<(), ProcessError> {
   // do some stuff
  }
}

The only thing that I found to solve the error was to remove any <'a> or <'_> declarations and make the downstream methods consume clients such as d and s in the above example. Using references didn't remove the error. Unsure whether using Arc<T> would.

Thanks for your time!

Any chance of a minimal example, e.g. runnable in the playground? Or a repo perhaps? There are a lot of missing pieces (type declarations, function signatures) and also typos, so I can't even guess at where to start making something testable / a reproduction to attempt explaination against.

As one example (from multiple):

pub trait ProcessableEvent {
  fn process<'a>(
    &self,
    context: ProcessableEventContext
  ) -> impl std::future::Future<Output = Result<(), ProcessError>> + send;
}

'a is unused so why is even there. Is that an pasting mistake? And are ProcessableEventContext or ProcessError parameterized by lifetimes? (They could be elided, and I don't trust the signature anyway because it says + send not + Send.)