From 78506f17149e08594c1a120f1df828411772a0b8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Mar 2025 17:57:14 -0700 Subject: [PATCH 1/2] Add regression test for issue 288 --- tests/test.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/test.rs b/tests/test.rs index 1772e75..0b6a322 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1705,3 +1705,24 @@ pub mod issue283 { } } } + +// https://github.com/dtolnay/async-trait/issues/288 +pub mod issue288 { + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + async fn f<#[cfg(any())] T: Send>(#[cfg(any())] t: T); + async fn g<#[cfg(all())] T: Send>(#[cfg(all())] t: T); + } + + pub struct Struct; + + #[async_trait] + impl Trait for Struct { + async fn f<#[cfg(any())] T: Send>(#[cfg(any())] t: T) {} + async fn g<#[cfg(all())] T: Send>(#[cfg(all())] t: T) { + let _ = t; + } + } +} From d3059849a4024425f80f0713bc802d8959290d96 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Mar 2025 17:53:22 -0700 Subject: [PATCH 2/2] Fix lifetime bounding on generic parameters that have cfg --- src/expand.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/expand.rs b/src/expand.rs index cfaa11c..573ad1d 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -192,10 +192,14 @@ fn transform_sig( Some(colon_token) => colon_token.span, None => param_name.span(), }; - let bounds = mem::take(&mut param.bounds); - where_clause_or_default(&mut sig.generics.where_clause) - .predicates - .push(parse_quote_spanned!(span=> #param_name: 'async_trait + #bounds)); + if param.attrs.is_empty() { + let bounds = mem::take(&mut param.bounds); + where_clause_or_default(&mut sig.generics.where_clause) + .predicates + .push(parse_quote_spanned!(span=> #param_name: 'async_trait + #bounds)); + } else { + param.bounds.push(parse_quote!('async_trait)); + } } GenericParam::Lifetime(param) => { let param_name = ¶m.lifetime; @@ -203,10 +207,14 @@ fn transform_sig( Some(colon_token) => colon_token.span, None => param_name.span(), }; - let bounds = mem::take(&mut param.bounds); - where_clause_or_default(&mut sig.generics.where_clause) - .predicates - .push(parse_quote_spanned!(span=> #param: 'async_trait + #bounds)); + if param.attrs.is_empty() { + let bounds = mem::take(&mut param.bounds); + where_clause_or_default(&mut sig.generics.where_clause) + .predicates + .push(parse_quote_spanned!(span=> #param: 'async_trait + #bounds)); + } else { + param.bounds.push(parse_quote!('async_trait)); + } } GenericParam::Const(_) => {} }