Change:
Async functions that take references seem to always trigger the lint (which is allow-by-default). Example: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I found which describes basically the same problem.
Seeing as this lint is not enabled by default, marking as deferred, though this would be good to fix and probably not too hard.
claim
Looks the same issue as . A little inelegant but if we can suppress the lint I think...

Discussion:
match param.kind { GenericParamKind::Lifetime { .. } => { let (name, reg) = Region::early(&self.tcx.hir(), &mut index, &param); <ins> let def_id = if let Region::EarlyBound(_ ,def_id , _) = reg { def_id } else { bug!(); }; </ins> if let hir::ParamName::Plain(param_name) = name { if param_name.name == kw::UnderscoreLifetime { // Pick the elided lifetime "definition" if one exists // and use it to make an elision scope. <ins> self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many); </ins> elision = Some(reg); } else { lifetimes.insert(name, reg); } } else { <ins> self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many); </ins> lifetimes.insert(name, reg); } }

_ => None, } { debug!("id = {:?} span = {:?} name = {:?}", id, span, name); if name.name == kw::UnderscoreLifetime { continue; }

<ins> // edition:2018 // Avoid spurious warnings of unused lifetime. The below async functions // are desugered to have an unused lifetime // but we don't want to warn about that as there's nothing they can do about it. #![deny(unused_lifetimes)] #![allow(dead_code)] pub async fn october(s: &str) { println!("{}", s); } pub async fn async_fn(&mut ref s: &mut[i32]) { println!("{:?}", s); } macro_rules! foo_macro { () => { pub async fn async_fn_in_macro(&mut ref _s: &mut[i32]) {} }; } foo_macro!(); pub async fn func_with_unused_lifetime<'a>(s: &'a str) { //~^ ERROR lifetime parameter `'a` never used println!("{}", s); } pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) { //~^ ERROR lifetime parameter `'a` never used //~^^ ERROR lifetime parameter `'b` never used println!("{}", s); } pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) { //~^ ERROR lifetime parameter `'c` never used println!("{}", s); } fn main() {} </ins>

<ins> error: lifetime parameter `'a` never used --> $DIR/unused-lifetime.rs:26:40 | LL | pub async fn func_with_unused_lifetime<'a>(s: &'a str) { |                                        ^^ | note: lint level defined here --> $DIR/unused-lifetime.rs:7:9 | LL | #![deny(unused_lifetimes)] |         ^^^^^^^^^^^^^^^^ error: lifetime parameter `'a` never used --> $DIR/unused-lifetime.rs:31:44 | LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) { |                                            ^^ error: lifetime parameter `'b` never used --> $DIR/unused-lifetime.rs:31:48 | LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) { |                                                ^^ error: lifetime parameter `'c` never used --> $DIR/unused-lifetime.rs:37:54 | LL | pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) { |                                                      ^^ error: aborting due to 4 previous errors </ins>