Upgrade rust/crates/async-trait to 0.1.48 Test: make Change-Id: I898f35cd086b1bd9952eba11d5d59d31f78a5d16
diff --git a/tests/executor/mod.rs b/tests/executor/mod.rs index f48b348..912fb79 100644 --- a/tests/executor/mod.rs +++ b/tests/executor/mod.rs
@@ -4,6 +4,7 @@ use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; // Executor for a future that resolves immediately (test only). +#[allow(clippy::missing_panics_doc)] pub fn block_on_simple<F: Future>(mut fut: F) -> F::Output { unsafe fn clone(_null: *const ()) -> RawWaker { unimplemented!()
diff --git a/tests/test.rs b/tests/test.rs index 5fc238b..604d092 100644 --- a/tests/test.rs +++ b/tests/test.rs
@@ -1,6 +1,12 @@ #![cfg_attr( async_trait_nightly_testing, - feature(min_specialization, min_const_generics) + feature(min_specialization, min_const_generics, type_alias_impl_trait) +)] +#![allow( + clippy::let_underscore_drop, + clippy::let_unit_value, + clippy::missing_panics_doc, + clippy::trivially_copy_pass_by_ref )] use async_trait::async_trait; @@ -151,6 +157,79 @@ #[async_trait] unsafe trait UnsafeTraitPrivate {} +pub async fn test_can_destruct() { + #[async_trait] + trait CanDestruct { + async fn f(&self, foos: (u8, u8, u8, u8)); + } + + #[async_trait] + impl CanDestruct for Struct { + async fn f(&self, (a, ref mut b, ref c, d): (u8, u8, u8, u8)) { + let _a: u8 = a; + let _b: &mut u8 = b; + let _c: &u8 = c; + let _d: u8 = d; + } + } +} + +pub async fn test_self_in_macro() { + #[async_trait] + trait Trait { + async fn a(self); + async fn b(&mut self); + async fn c(&self); + } + + #[async_trait] + impl Trait for String { + async fn a(self) { + println!("{}", self); + } + async fn b(&mut self) { + println!("{}", self); + } + async fn c(&self) { + println!("{}", self); + } + } +} + +pub async fn test_inference() { + #[async_trait] + pub trait Trait { + async fn f() -> Box<dyn Iterator<Item = ()>> { + Box::new(std::iter::empty()) + } + } +} + +pub async fn test_internal_items() { + #[async_trait] + #[allow(dead_code, clippy::items_after_statements)] + pub trait Trait: Sized { + async fn f(self) { + struct Struct; + + impl Struct { + fn f(self) { + let _ = self; + } + } + } + } +} + +pub async fn test_unimplemented() { + #[async_trait] + pub trait Trait { + async fn f() { + unimplemented!() + } + } +} + // https://github.com/dtolnay/async-trait/issues/1 pub mod issue1 { use async_trait::async_trait; @@ -536,6 +615,7 @@ } #[test] + #[should_panic] fn tracing() { // Create the future outside of the subscriber, as no call to tracing // should be made until the future is polled. @@ -1077,3 +1157,168 @@ } } } + +// https://github.com/dtolnay/async-trait/pull/125#pullrequestreview-491880881 +pub mod drop_order { + use crate::executor; + use async_trait::async_trait; + use std::sync::atomic::{AtomicBool, Ordering}; + + struct Flagger<'a>(&'a AtomicBool); + + impl Drop for Flagger<'_> { + fn drop(&mut self) { + self.0.fetch_xor(true, Ordering::AcqRel); + } + } + + #[async_trait] + trait Trait { + async fn async_trait(_: Flagger<'_>, flag: &AtomicBool); + } + + struct Struct; + + #[async_trait] + impl Trait for Struct { + async fn async_trait(_: Flagger<'_>, flag: &AtomicBool) { + flag.fetch_or(true, Ordering::AcqRel); + } + } + + async fn standalone(_: Flagger<'_>, flag: &AtomicBool) { + flag.fetch_or(true, Ordering::AcqRel); + } + + #[async_trait] + trait SelfTrait { + async fn async_trait(self, flag: &AtomicBool); + } + + #[async_trait] + impl SelfTrait for Flagger<'_> { + async fn async_trait(self, flag: &AtomicBool) { + flag.fetch_or(true, Ordering::AcqRel); + } + } + + #[test] + fn test_drop_order() { + // 0 : 0 ^ 1 = 1 | 1 = 1 (if flagger then block) + // 0 : 0 | 1 = 1 ^ 1 = 0 (if block then flagger) + + let flag = AtomicBool::new(false); + executor::block_on_simple(standalone(Flagger(&flag), &flag)); + assert!(!flag.load(Ordering::Acquire)); + + executor::block_on_simple(Struct::async_trait(Flagger(&flag), &flag)); + assert!(!flag.load(Ordering::Acquire)); + + executor::block_on_simple(Flagger(&flag).async_trait(&flag)); + assert!(!flag.load(Ordering::Acquire)); + } +} + +// https://github.com/dtolnay/async-trait/issues/145 +pub mod issue145 { + #![deny(clippy::type_complexity)] + + use async_trait::async_trait; + + #[async_trait] + pub trait ManageConnection: Sized + Send + Sync + 'static { + type Connection: Send + 'static; + type Error: Send + 'static; + + async fn connect(&self) -> Result<Self::Connection, Self::Error>; + } +} + +// https://github.com/dtolnay/async-trait/issues/147 +pub mod issue147 { + #![deny(clippy::let_unit_value)] + + use async_trait::async_trait; + + pub struct MyType; + + #[async_trait] + pub trait MyTrait { + async fn x(); + async fn y() -> (); + async fn z(); + } + + #[async_trait] + impl MyTrait for MyType { + async fn x() {} + async fn y() -> () {} + async fn z() { + unimplemented!() + } + } +} + +// https://github.com/dtolnay/async-trait/issues/149 +pub mod issue149 { + use async_trait::async_trait; + + pub struct Thing; + pub trait Ret {} + impl Ret for Thing {} + + pub async fn ok() -> &'static dyn Ret { + return &Thing; + } + + #[async_trait] + pub trait Trait { + async fn fail() -> &'static dyn Ret { + return &Thing; + } + } +} + +// https://github.com/dtolnay/async-trait/issues/152 +#[cfg(async_trait_nightly_testing)] +pub mod issue152 { + use async_trait::async_trait; + + #[async_trait] + trait Trait { + type Assoc; + + async fn f(&self) -> Self::Assoc; + } + + struct Struct; + + #[async_trait] + impl Trait for Struct { + type Assoc = impl Sized; + + async fn f(&self) -> Self::Assoc {} + } +} + +// https://github.com/dtolnay/async-trait/issues/154 +pub mod issue154 { + #![deny(clippy::items_after_statements)] + + use async_trait::async_trait; + + #[async_trait] + pub trait MyTrait { + async fn f(&self); + } + + pub struct Struct; + + #[async_trait] + impl MyTrait for Struct { + async fn f(&self) { + const MAX: u16 = 128; + println!("{}", MAX); + } + } +}
diff --git a/tests/ui/delimiter-span.rs b/tests/ui/delimiter-span.rs index 68456fa..d3f67a1 100644 --- a/tests/ui/delimiter-span.rs +++ b/tests/ui/delimiter-span.rs
@@ -1,7 +1,7 @@ use async_trait::async_trait; macro_rules! picky { - (ident) => {}; + ($(t:tt)*) => {}; } #[async_trait] @@ -14,6 +14,7 @@ #[async_trait] impl Trait for Struct { async fn method() { + picky!({ 123, self }); picky!({ 123 }); } }
diff --git a/tests/ui/delimiter-span.stderr b/tests/ui/delimiter-span.stderr index e080445..6120262 100644 --- a/tests/ui/delimiter-span.stderr +++ b/tests/ui/delimiter-span.stderr
@@ -4,5 +4,14 @@ 3 | macro_rules! picky { | ------------------ when calling this macro ... -17 | picky!({ 123 }); +17 | picky!({ 123, self }); + | ^ no rules expected this token in macro call + +error: no rules expected the token `{` + --> $DIR/delimiter-span.rs:18:16 + | +3 | macro_rules! picky { + | ------------------ when calling this macro +... +18 | picky!({ 123 }); | ^ no rules expected this token in macro call
diff --git a/tests/ui/lifetime-span.rs b/tests/ui/lifetime-span.rs new file mode 100644 index 0000000..4e9e5d9 --- /dev/null +++ b/tests/ui/lifetime-span.rs
@@ -0,0 +1,36 @@ +use async_trait::async_trait; + +struct A; +struct B; + +#[async_trait] +pub trait Trait<'r> { + async fn method(&'r self); +} + +#[async_trait] +impl Trait for A { + async fn method(&self) { } +} + +#[async_trait] +impl<'r> Trait<'r> for B { + async fn method(&self) { } +} + +#[async_trait] +pub trait Trait2 { + async fn method<'r>(&'r self); +} + +#[async_trait] +impl Trait2 for A { + async fn method(&self) { } +} + +#[async_trait] +impl<'r> Trait2<'r> for B { + async fn method(&'r self) { } +} + +fn main() {}
diff --git a/tests/ui/lifetime-span.stderr b/tests/ui/lifetime-span.stderr new file mode 100644 index 0000000..feae87f --- /dev/null +++ b/tests/ui/lifetime-span.stderr
@@ -0,0 +1,46 @@ +error[E0726]: implicit elided lifetime not allowed here + --> $DIR/lifetime-span.rs:12:6 + | +12 | impl Trait for A { + | ^^^^^- help: indicate the anonymous lifetime: `<'_>` + +error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/lifetime-span.rs:32:10 + | +32 | impl<'r> Trait2<'r> for B { + | ^^^^^^---- help: remove these generics + | | + | expected 0 lifetime arguments + | +note: trait defined here, with 0 lifetime parameters + --> $DIR/lifetime-span.rs:22:11 + | +22 | pub trait Trait2 { + | ^^^^^^ + +error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration + --> $DIR/lifetime-span.rs:13:14 + | +8 | async fn method(&'r self); + | ---------------- lifetimes in impl do not match this method in trait +... +13 | async fn method(&self) { } + | ^^^^^^^^^^^^^ lifetimes do not match method in trait + +error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration + --> $DIR/lifetime-span.rs:18:14 + | +8 | async fn method(&'r self); + | ---------------- lifetimes in impl do not match this method in trait +... +18 | async fn method(&self) { } + | ^^^^^^^^^^^^^ lifetimes do not match method in trait + +error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration + --> $DIR/lifetime-span.rs:33:14 + | +23 | async fn method<'r>(&'r self); + | ---- lifetimes in impl do not match this method in trait +... +33 | async fn method(&'r self) { } + | ^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
diff --git a/tests/ui/self-span.stderr b/tests/ui/self-span.stderr index fb11528..9ea1bbe 100644 --- a/tests/ui/self-span.stderr +++ b/tests/ui/self-span.stderr
@@ -1,12 +1,3 @@ -error[E0423]: expected value, found struct `S` - --> $DIR/self-span.rs:18:23 - | -3 | pub struct S {} - | --------------- `S` defined here -... -18 | let _: Self = Self; - | ^^^^ help: use struct literal syntax instead: `S {}` - error[E0308]: mismatched types --> $DIR/self-span.rs:17:21 | @@ -15,6 +6,12 @@ | | | expected due to this +error: the `Self` constructor can only be used with tuple or unit structs + --> $DIR/self-span.rs:18:23 + | +18 | let _: Self = Self; + | ^^^^ help: use curly brackets: `Self { /* fields */ }` + error[E0308]: mismatched types --> $DIR/self-span.rs:25:21 |
diff --git a/tests/ui/send-not-implemented.rs b/tests/ui/send-not-implemented.rs index a3e3856..d8883fb 100644 --- a/tests/ui/send-not-implemented.rs +++ b/tests/ui/send-not-implemented.rs
@@ -10,6 +10,13 @@ let _guard = mutex.lock().unwrap(); f().await; } + + async fn test_ret(&self) -> bool { + let mutex = Mutex::new(()); + let _guard = mutex.lock().unwrap(); + f().await; + true + } } fn main() {}
diff --git a/tests/ui/send-not-implemented.stderr b/tests/ui/send-not-implemented.stderr index 05c445b..473a31b 100644 --- a/tests/ui/send-not-implemented.stderr +++ b/tests/ui/send-not-implemented.stderr
@@ -7,7 +7,7 @@ 10 | | let _guard = mutex.lock().unwrap(); 11 | | f().await; 12 | | } - | |_____^ future returned by `__test` is not `Send` + | |_____^ future created by async block is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` note: future is not `Send` as this value is used across an await @@ -20,3 +20,28 @@ 12 | } | - `_guard` is later dropped here = note: required for the cast to the object type `dyn Future<Output = ()> + Send` + +error: future cannot be sent between threads safely + --> $DIR/send-not-implemented.rs:14:38 + | +14 | async fn test_ret(&self) -> bool { + | ______________________________________^ +15 | | let mutex = Mutex::new(()); +16 | | let _guard = mutex.lock().unwrap(); +17 | | f().await; +18 | | true +19 | | } + | |_____^ future created by async block is not `Send` + | + = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` +note: future is not `Send` as this value is used across an await + --> $DIR/send-not-implemented.rs:17:9 + | +16 | let _guard = mutex.lock().unwrap(); + | ------ has type `MutexGuard<'_, ()>` which is not `Send` +17 | f().await; + | ^^^^^^^^^ await occurs here, with `_guard` maybe used later +18 | true +19 | } + | - `_guard` is later dropped here + = note: required for the cast to the object type `dyn Future<Output = bool> + Send`
diff --git a/tests/ui/unreachable.rs b/tests/ui/unreachable.rs new file mode 100644 index 0000000..f546a58 --- /dev/null +++ b/tests/ui/unreachable.rs
@@ -0,0 +1,20 @@ +#![deny(warnings)] + +use async_trait::async_trait; + +#[async_trait] +pub trait Trait { + async fn f() { + unimplemented!() + } +} + +#[async_trait] +pub trait TraitFoo { + async fn f() { + let y = unimplemented!(); + let z = y; + } +} + +fn main() {}
diff --git a/tests/ui/unreachable.stderr b/tests/ui/unreachable.stderr new file mode 100644 index 0000000..0b74692 --- /dev/null +++ b/tests/ui/unreachable.stderr
@@ -0,0 +1,14 @@ +error: unreachable statement + --> $DIR/unreachable.rs:16:9 + | +15 | let y = unimplemented!(); + | ---------------- any code following this expression is unreachable +16 | let z = y; + | ^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> $DIR/unreachable.rs:1:9 + | +1 | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unreachable_code)]` implied by `#[deny(warnings)]`
diff --git a/tests/ui/unsupported-self.stderr b/tests/ui/unsupported-self.stderr index c1ea955..c98807e 100644 --- a/tests/ui/unsupported-self.stderr +++ b/tests/ui/unsupported-self.stderr
@@ -1,4 +1,4 @@ -error: Self type of this impl is unsupported in expression position +error: the `Self` constructor can only be used with tuple or unit structs --> $DIR/unsupported-self.rs:11:17 | 11 | let _ = Self;