diff --git a/Cargo.toml b/Cargo.toml index fa2b8b9..9b8611e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ quote = "1.0" syn = { version = "1.0.61", features = ["full", "visit-mut"] } [dev-dependencies] +futures = "0.3" rustversion = "1.0" tracing = "0.1.14" tracing-attributes = "0.1.14" diff --git a/src/receiver.rs b/src/receiver.rs index 7f837f4..f6ea327 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -151,9 +151,16 @@ impl VisitMut for ReplaceSelf { fn visit_item_mut(&mut self, i: &mut Item) { // Visit `macro_rules!` because locally defined macros can refer to - // `self`. Otherwise, do not recurse into nested items. + // `self`. + // + // Visit `futures::select` and similar select macros, which commonly + // appear syntactically like an item despite expanding to an expression. + // + // Otherwise, do not recurse into nested items. if let Item::Macro(i) = i { - if i.mac.path.is_ident("macro_rules") { + if i.mac.path.is_ident("macro_rules") + || i.mac.path.segments.last().unwrap().ident == "select" + { self.visit_macro_mut(&mut i.mac) } } diff --git a/tests/test.rs b/tests/test.rs index 5af9f6d..6f95576 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1335,3 +1335,29 @@ pub mod issue158 { } } } + +// https://github.com/dtolnay/async-trait/issues/161 +#[allow(clippy::mut_mut)] +pub mod issue161 { + use async_trait::async_trait; + use futures::future::FutureExt; + use std::sync::Arc; + + #[async_trait] + pub trait Trait { + async fn f(self: Arc); + } + + pub struct MyStruct(bool); + + #[async_trait] + impl Trait for MyStruct { + async fn f(self: Arc) { + futures::select! { + _ = async { + println!("{}", self.0); + }.fuse() => {} + } + } + } +}