summaryrefslogtreecommitdiffstats
path: root/third_party/rust/async-trait/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/async-trait/tests
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/async-trait/tests')
-rw-r--r--third_party/rust/async-trait/tests/compiletest.rs7
-rw-r--r--third_party/rust/async-trait/tests/executor/mod.rs36
-rw-r--r--third_party/rust/async-trait/tests/test.rs1463
-rw-r--r--third_party/rust/async-trait/tests/ui/arg-implementation-detail.rs22
-rw-r--r--third_party/rust/async-trait/tests/ui/arg-implementation-detail.stderr5
-rw-r--r--third_party/rust/async-trait/tests/ui/bare-trait-object.rs15
-rw-r--r--third_party/rust/async-trait/tests/ui/bare-trait-object.stderr21
-rw-r--r--third_party/rust/async-trait/tests/ui/consider-restricting.rs26
-rw-r--r--third_party/rust/async-trait/tests/ui/consider-restricting.stderr33
-rw-r--r--third_party/rust/async-trait/tests/ui/delimiter-span.rs24
-rw-r--r--third_party/rust/async-trait/tests/ui/delimiter-span.stderr21
-rw-r--r--third_party/rust/async-trait/tests/ui/lifetime-span.rs36
-rw-r--r--third_party/rust/async-trait/tests/ui/lifetime-span.stderr25
-rw-r--r--third_party/rust/async-trait/tests/ui/missing-async-in-impl.rs15
-rw-r--r--third_party/rust/async-trait/tests/ui/missing-async-in-impl.stderr8
-rw-r--r--third_party/rust/async-trait/tests/ui/missing-async-in-trait.rs15
-rw-r--r--third_party/rust/async-trait/tests/ui/missing-async-in-trait.stderr8
-rw-r--r--third_party/rust/async-trait/tests/ui/missing-body.rs15
-rw-r--r--third_party/rust/async-trait/tests/ui/missing-body.stderr7
-rw-r--r--third_party/rust/async-trait/tests/ui/must-use.rs21
-rw-r--r--third_party/rust/async-trait/tests/ui/must-use.stderr11
-rw-r--r--third_party/rust/async-trait/tests/ui/self-span.rs30
-rw-r--r--third_party/rust/async-trait/tests/ui/self-span.stderr27
-rw-r--r--third_party/rust/async-trait/tests/ui/send-not-implemented.rs22
-rw-r--r--third_party/rust/async-trait/tests/ui/send-not-implemented.stderr47
-rw-r--r--third_party/rust/async-trait/tests/ui/unreachable.rs20
-rw-r--r--third_party/rust/async-trait/tests/ui/unreachable.stderr14
-rw-r--r--third_party/rust/async-trait/tests/ui/unsupported-self.rs15
-rw-r--r--third_party/rust/async-trait/tests/ui/unsupported-self.stderr5
29 files changed, 2014 insertions, 0 deletions
diff --git a/third_party/rust/async-trait/tests/compiletest.rs b/third_party/rust/async-trait/tests/compiletest.rs
new file mode 100644
index 0000000000..7974a6249e
--- /dev/null
+++ b/third_party/rust/async-trait/tests/compiletest.rs
@@ -0,0 +1,7 @@
+#[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/*.rs");
+}
diff --git a/third_party/rust/async-trait/tests/executor/mod.rs b/third_party/rust/async-trait/tests/executor/mod.rs
new file mode 100644
index 0000000000..912fb79844
--- /dev/null
+++ b/third_party/rust/async-trait/tests/executor/mod.rs
@@ -0,0 +1,36 @@
+use std::future::Future;
+use std::pin::Pin;
+use std::ptr;
+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!()
+ }
+
+ unsafe fn wake(_null: *const ()) {
+ unimplemented!()
+ }
+
+ unsafe fn wake_by_ref(_null: *const ()) {
+ unimplemented!()
+ }
+
+ unsafe fn drop(_null: *const ()) {}
+
+ let data = ptr::null();
+ let vtable = &RawWakerVTable::new(clone, wake, wake_by_ref, drop);
+ let raw_waker = RawWaker::new(data, vtable);
+ let waker = unsafe { Waker::from_raw(raw_waker) };
+ let mut cx = Context::from_waker(&waker);
+
+ // fut does not move until it gets dropped.
+ let fut = unsafe { Pin::new_unchecked(&mut fut) };
+
+ match fut.poll(&mut cx) {
+ Poll::Ready(output) => output,
+ Poll::Pending => panic!("future did not resolve immediately"),
+ }
+}
diff --git a/third_party/rust/async-trait/tests/test.rs b/third_party/rust/async-trait/tests/test.rs
new file mode 100644
index 0000000000..23d8f801fd
--- /dev/null
+++ b/third_party/rust/async-trait/tests/test.rs
@@ -0,0 +1,1463 @@
+#![cfg_attr(
+ async_trait_nightly_testing,
+ feature(min_specialization, type_alias_impl_trait)
+)]
+#![allow(
+ clippy::let_unit_value,
+ clippy::missing_panics_doc,
+ clippy::missing_safety_doc,
+ clippy::needless_return,
+ clippy::trivially_copy_pass_by_ref,
+ clippy::unused_async
+)]
+
+use async_trait::async_trait;
+
+pub mod executor;
+
+// Dummy module to check that the expansion refer to rust's core crate
+mod core {}
+
+#[async_trait]
+trait Trait {
+ type Assoc;
+
+ async fn selfvalue(self)
+ where
+ Self: Sized,
+ {
+ }
+
+ async fn selfref(&self) {}
+
+ async fn selfmut(&mut self) {}
+
+ async fn required() -> Self::Assoc;
+
+ async fn elided_lifetime(_x: &str) {}
+
+ async fn explicit_lifetime<'a>(_x: &'a str) {}
+
+ async fn generic_type_param<T: Send>(x: Box<T>) -> T {
+ *x
+ }
+
+ async fn calls(&self) {
+ self.selfref().await;
+ Self::elided_lifetime("").await;
+ <Self>::elided_lifetime("").await;
+ }
+
+ async fn calls_mut(&mut self) {
+ self.selfmut().await;
+ }
+}
+
+struct Struct;
+
+#[async_trait]
+impl Trait for Struct {
+ type Assoc = ();
+
+ async fn selfvalue(self) {}
+
+ async fn selfref(&self) {}
+
+ async fn selfmut(&mut self) {}
+
+ async fn required() -> Self::Assoc {}
+
+ async fn elided_lifetime(_x: &str) {}
+
+ async fn explicit_lifetime<'a>(_x: &'a str) {}
+
+ async fn generic_type_param<T: Send>(x: Box<T>) -> T {
+ *x
+ }
+
+ async fn calls(&self) {
+ self.selfref().await;
+ Self::elided_lifetime("").await;
+ <Self>::elided_lifetime("").await;
+ }
+
+ async fn calls_mut(&mut self) {
+ self.selfmut().await;
+ }
+}
+
+pub async fn test() {
+ let mut s = Struct;
+ s.selfref().await;
+ s.selfmut().await;
+ s.selfvalue().await;
+
+ Struct::required().await;
+ Struct::elided_lifetime("").await;
+ Struct::explicit_lifetime("").await;
+ Struct::generic_type_param(Box::new("")).await;
+
+ let mut s = Struct;
+ s.calls().await;
+ s.calls_mut().await;
+}
+
+pub async fn test_object_safe_without_default() {
+ #[async_trait]
+ trait ObjectSafe {
+ async fn f(&self);
+ }
+
+ #[async_trait]
+ impl ObjectSafe for Struct {
+ async fn f(&self) {}
+ }
+
+ let object = &Struct as &dyn ObjectSafe;
+ object.f().await;
+}
+
+pub async fn test_object_safe_with_default() {
+ #[async_trait]
+ trait ObjectSafe: Sync {
+ async fn f(&self) {}
+ }
+
+ #[async_trait]
+ impl ObjectSafe for Struct {
+ async fn f(&self) {}
+ }
+
+ let object = &Struct as &dyn ObjectSafe;
+ object.f().await;
+}
+
+pub async fn test_object_no_send() {
+ #[async_trait(?Send)]
+ trait ObjectSafe: Sync {
+ async fn f(&self) {}
+ }
+
+ #[async_trait(?Send)]
+ impl ObjectSafe for Struct {
+ async fn f(&self) {}
+ }
+
+ let object = &Struct as &dyn ObjectSafe;
+ object.f().await;
+}
+
+#[async_trait]
+pub unsafe trait UnsafeTrait {}
+
+#[async_trait]
+unsafe impl UnsafeTrait for () {}
+
+#[async_trait]
+pub(crate) unsafe trait UnsafeTraitPubCrate {}
+
+#[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;
+
+ #[async_trait]
+ trait Issue1 {
+ async fn f<U>(&self);
+ }
+
+ #[async_trait]
+ impl<T: Sync> Issue1 for Vec<T> {
+ async fn f<U>(&self) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/2
+pub mod issue2 {
+ use async_trait::async_trait;
+ use std::future::Future;
+
+ #[async_trait]
+ pub trait Issue2: Future {
+ async fn flatten(self) -> <Self::Output as Future>::Output
+ where
+ Self::Output: Future + Send,
+ Self: Sized,
+ {
+ let nested_future = self.await;
+ nested_future.await
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/9
+pub mod issue9 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Issue9: Sized + Send {
+ async fn f(_x: Self) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/11
+pub mod issue11 {
+ use async_trait::async_trait;
+ use std::sync::Arc;
+
+ #[async_trait]
+ trait Issue11 {
+ async fn example(self: Arc<Self>);
+ }
+
+ struct Struct;
+
+ #[async_trait]
+ impl Issue11 for Struct {
+ async fn example(self: Arc<Self>) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/15
+pub mod issue15 {
+ use async_trait::async_trait;
+ use std::marker::PhantomData;
+
+ trait Trait {}
+
+ #[async_trait]
+ trait Issue15 {
+ async fn myfn(&self, _: PhantomData<dyn Trait + Send>) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/17
+pub mod issue17 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ trait Issue17 {
+ async fn f(&self);
+ }
+
+ struct Struct {
+ string: String,
+ }
+
+ #[async_trait]
+ impl Issue17 for Struct {
+ async fn f(&self) {
+ println!("{}", self.string);
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/23
+pub mod issue23 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Issue23 {
+ async fn f(self);
+
+ async fn g(mut self)
+ where
+ Self: Sized,
+ {
+ do_something(&mut self);
+ }
+ }
+
+ struct S {}
+
+ #[async_trait]
+ impl Issue23 for S {
+ async fn f(mut self) {
+ do_something(&mut self);
+ }
+ }
+
+ fn do_something<T>(_: &mut T) {}
+}
+
+// https://github.com/dtolnay/async-trait/issues/25
+#[cfg(async_trait_nightly_testing)]
+pub mod issue25 {
+ use crate::executor;
+ use async_trait::async_trait;
+ use std::fmt::{Display, Write};
+
+ #[async_trait]
+ trait AsyncToString {
+ async fn async_to_string(&self) -> String;
+ }
+
+ #[async_trait]
+ impl AsyncToString for String {
+ async fn async_to_string(&self) -> String {
+ "special".to_owned()
+ }
+ }
+
+ macro_rules! hide_from_stable_parser {
+ ($($tt:tt)*) => {
+ $($tt)*
+ };
+ }
+
+ hide_from_stable_parser! {
+ #[async_trait]
+ impl<T: ?Sized + Display + Sync> AsyncToString for T {
+ default async fn async_to_string(&self) -> String {
+ let mut buf = String::new();
+ buf.write_fmt(format_args!("{}", self)).unwrap();
+ buf
+ }
+ }
+ }
+
+ #[test]
+ fn test() {
+ let fut = true.async_to_string();
+ assert_eq!(executor::block_on_simple(fut), "true");
+
+ let string = String::new();
+ let fut = string.async_to_string();
+ assert_eq!(executor::block_on_simple(fut), "special");
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/28
+pub mod issue28 {
+ use async_trait::async_trait;
+
+ struct Str<'a>(&'a str);
+
+ #[async_trait]
+ trait Trait1<'a> {
+ async fn f(x: Str<'a>) -> &'a str;
+ async fn g(x: Str<'a>) -> &'a str {
+ x.0
+ }
+ }
+
+ #[async_trait]
+ impl<'a> Trait1<'a> for str {
+ async fn f(x: Str<'a>) -> &'a str {
+ x.0
+ }
+ }
+
+ #[async_trait]
+ trait Trait2 {
+ async fn f();
+ }
+
+ #[async_trait]
+ impl<'a> Trait2 for &'a () {
+ async fn f() {}
+ }
+
+ #[async_trait]
+ trait Trait3<'a, 'b> {
+ async fn f(_: &'a &'b ()); // chain 'a and 'b
+ async fn g(_: &'b ()); // chain 'b only
+ async fn h(); // do not chain
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/31
+pub mod issue31 {
+ use async_trait::async_trait;
+
+ pub struct Struct<'a> {
+ pub name: &'a str,
+ }
+
+ #[async_trait]
+ pub trait Trait<'a> {
+ async fn hello(thing: Struct<'a>) -> String;
+ async fn hello_twice(one: Struct<'a>, two: Struct<'a>) -> String {
+ let str1 = Self::hello(one).await;
+ let str2 = Self::hello(two).await;
+ str1 + &str2
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/42
+pub mod issue42 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Context: Sized {
+ async fn from_parts() -> Self;
+ }
+
+ pub struct TokenContext;
+
+ #[async_trait]
+ impl Context for TokenContext {
+ async fn from_parts() -> TokenContext {
+ TokenContext
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/44
+pub mod issue44 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait StaticWithWhereSelf
+ where
+ Box<Self>: Sized,
+ Self: Sized + Send,
+ {
+ async fn get_one() -> u8 {
+ 1
+ }
+ }
+
+ pub struct Struct;
+
+ #[async_trait]
+ impl StaticWithWhereSelf for Struct {}
+}
+
+// https://github.com/dtolnay/async-trait/issues/45
+pub mod issue45 {
+ use crate::executor;
+ use async_trait::async_trait;
+ use std::fmt::Debug;
+ use std::sync::atomic::{AtomicU64, Ordering};
+ use std::sync::{Arc, Mutex};
+ use tracing::event::Event;
+ use tracing::field::{Field, Visit};
+ use tracing::span::{Attributes, Id, Record};
+ use tracing::{info, instrument, subscriber, Metadata, Subscriber};
+
+ #[async_trait]
+ pub trait Parent {
+ async fn foo(&mut self, v: usize);
+ }
+
+ #[async_trait]
+ pub trait Child {
+ async fn bar(&self);
+ }
+
+ #[derive(Debug)]
+ struct Impl(usize);
+
+ #[async_trait]
+ impl Parent for Impl {
+ #[instrument]
+ async fn foo(&mut self, v: usize) {
+ self.0 = v;
+ self.bar().await;
+ }
+ }
+
+ #[async_trait]
+ impl Child for Impl {
+ // Let's check that tracing detects the renaming of the `self` variable
+ // too, as tracing::instrument is not going to be able to skip the
+ // `self` argument if it can't find it in the function signature.
+ #[instrument(skip(self))]
+ async fn bar(&self) {
+ info!(val = self.0);
+ }
+ }
+
+ // A simple subscriber implementation to test the behavior of async-trait
+ // with tokio-rs/tracing. This implementation is not robust against race
+ // conditions, but it's not an issue here as we are only polling on a single
+ // future at a time.
+ #[derive(Debug)]
+ struct SubscriberInner {
+ current_depth: AtomicU64,
+ // We assert that nested functions work. If the fix were to break, we
+ // would see two top-level functions instead of `bar` nested in `foo`.
+ max_depth: AtomicU64,
+ max_span_id: AtomicU64,
+ // Name of the variable / value / depth when the event was recorded.
+ value: Mutex<Option<(&'static str, u64, u64)>>,
+ }
+
+ #[derive(Debug, Clone)]
+ struct TestSubscriber {
+ inner: Arc<SubscriberInner>,
+ }
+
+ impl TestSubscriber {
+ fn new() -> Self {
+ TestSubscriber {
+ inner: Arc::new(SubscriberInner {
+ current_depth: AtomicU64::new(0),
+ max_depth: AtomicU64::new(0),
+ max_span_id: AtomicU64::new(1),
+ value: Mutex::new(None),
+ }),
+ }
+ }
+ }
+
+ struct U64Visitor(Option<(&'static str, u64)>);
+
+ impl Visit for U64Visitor {
+ fn record_debug(&mut self, _field: &Field, _value: &dyn Debug) {}
+
+ fn record_u64(&mut self, field: &Field, value: u64) {
+ self.0 = Some((field.name(), value));
+ }
+ }
+
+ impl Subscriber for TestSubscriber {
+ fn enabled(&self, _metadata: &Metadata) -> bool {
+ true
+ }
+ fn new_span(&self, _span: &Attributes) -> Id {
+ Id::from_u64(self.inner.max_span_id.fetch_add(1, Ordering::AcqRel))
+ }
+ fn record(&self, _span: &Id, _values: &Record) {}
+ fn record_follows_from(&self, _span: &Id, _follows: &Id) {}
+ fn event(&self, event: &Event) {
+ let mut visitor = U64Visitor(None);
+ event.record(&mut visitor);
+ if let Some((s, v)) = visitor.0 {
+ let current_depth = self.inner.current_depth.load(Ordering::Acquire);
+ *self.inner.value.lock().unwrap() = Some((s, v, current_depth));
+ }
+ }
+ fn enter(&self, _span: &Id) {
+ let old_depth = self.inner.current_depth.fetch_add(1, Ordering::AcqRel);
+ if old_depth + 1 > self.inner.max_depth.load(Ordering::Acquire) {
+ self.inner.max_depth.fetch_add(1, Ordering::AcqRel);
+ }
+ }
+ fn exit(&self, _span: &Id) {
+ self.inner.current_depth.fetch_sub(1, Ordering::AcqRel);
+ }
+ }
+
+ #[test]
+ #[cfg_attr(miri, ignore)] // https://github.com/matklad/once_cell/pull/185
+ fn tracing() {
+ // Create the future outside of the subscriber, as no call to tracing
+ // should be made until the future is polled.
+ let mut struct_impl = Impl(0);
+ let fut = struct_impl.foo(5);
+ let subscriber = TestSubscriber::new();
+ subscriber::with_default(subscriber.clone(), || executor::block_on_simple(fut));
+ // Did we enter bar inside of foo?
+ assert_eq!(subscriber.inner.max_depth.load(Ordering::Acquire), 2);
+ // Have we exited all spans?
+ assert_eq!(subscriber.inner.current_depth.load(Ordering::Acquire), 0);
+ // Did we create only two spans? Note: spans start at 1, hence the -1.
+ assert_eq!(subscriber.inner.max_span_id.load(Ordering::Acquire) - 1, 2);
+ // Was the value recorded at the right depth i.e. in the right function?
+ // If so, was it the expected value?
+ assert_eq!(*subscriber.inner.value.lock().unwrap(), Some(("val", 5, 2)));
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/46
+pub mod issue46 {
+ use async_trait::async_trait;
+
+ macro_rules! implement_commands_workaround {
+ ($tyargs:tt : $ty:tt) => {
+ #[async_trait]
+ pub trait AsyncCommands1: Sized {
+ async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
+ self.f(x).await
+ }
+ }
+ };
+ }
+
+ implement_commands_workaround!(K: Send);
+
+ macro_rules! implement_commands {
+ ($tyargs:ident : $ty:ident) => {
+ #[async_trait]
+ pub trait AsyncCommands2: Sized {
+ async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
+ self.f(x).await
+ }
+ }
+ };
+ }
+
+ implement_commands!(K: Send);
+}
+
+// https://github.com/dtolnay/async-trait/issues/53
+pub mod issue53 {
+ use async_trait::async_trait;
+
+ pub struct Unit;
+ pub struct Tuple(u8);
+ pub struct Struct {
+ pub x: u8,
+ }
+
+ #[async_trait]
+ pub trait Trait {
+ async fn method();
+ }
+
+ #[async_trait]
+ impl Trait for Unit {
+ async fn method() {
+ let _ = Self;
+ }
+ }
+
+ #[async_trait]
+ impl Trait for Tuple {
+ async fn method() {
+ let _ = Self(0);
+ }
+ }
+
+ #[async_trait]
+ impl Trait for Struct {
+ async fn method() {
+ let _ = Self { x: 0 };
+ }
+ }
+
+ #[async_trait]
+ impl Trait for std::marker::PhantomData<Struct> {
+ async fn method() {
+ let _ = Self;
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/57
+#[cfg(async_trait_nightly_testing)]
+pub mod issue57 {
+ use crate::executor;
+ use async_trait::async_trait;
+
+ #[async_trait]
+ trait Trait {
+ async fn const_generic<T: Send, const C: usize>(_: [T; C]) {}
+ }
+
+ struct Struct;
+
+ #[async_trait]
+ impl Trait for Struct {
+ async fn const_generic<T: Send, const C: usize>(_: [T; C]) {}
+ }
+
+ #[test]
+ fn test() {
+ let fut = Struct::const_generic([0; 10]);
+ executor::block_on_simple(fut);
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/68
+pub mod issue68 {
+ #[rustversion::since(1.40)] // procedural macros cannot expand to macro definitions in 1.39.
+ #[async_trait::async_trait]
+ pub trait Example {
+ async fn method(&self) {
+ macro_rules! t {
+ () => {{
+ let _: &Self = self;
+ }};
+ }
+ t!();
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/73
+pub mod issue73 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Example {
+ const ASSOCIATED: &'static str;
+
+ async fn associated(&self) {
+ println!("Associated:{}", Self::ASSOCIATED);
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/81
+pub mod issue81 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Trait {
+ async fn handle(&self);
+ }
+
+ pub enum Enum {
+ Variant,
+ }
+
+ #[async_trait]
+ impl Trait for Enum {
+ async fn handle(&self) {
+ let Enum::Variant = self;
+ let Self::Variant = self;
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/83
+pub mod issue83 {
+ #![allow(clippy::needless_arbitrary_self_type)]
+
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Trait {
+ async fn f(&self) {}
+ async fn g(self: &Self) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/85
+pub mod issue85 {
+ #![deny(non_snake_case)]
+
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Trait {
+ #[allow(non_snake_case)]
+ async fn camelCase();
+ }
+
+ pub struct Struct;
+
+ #[async_trait]
+ impl Trait for Struct {
+ async fn camelCase() {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/87
+pub mod issue87 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Trait {
+ async fn f(&self);
+ }
+
+ pub enum Tuple {
+ V(),
+ }
+
+ pub enum Struct {
+ V {},
+ }
+
+ #[async_trait]
+ impl Trait for Tuple {
+ async fn f(&self) {
+ let Tuple::V() = self;
+ let Self::V() = self;
+ let _ = Self::V;
+ let _ = Self::V();
+ }
+ }
+
+ #[async_trait]
+ impl Trait for Struct {
+ async fn f(&self) {
+ let Struct::V {} = self;
+ let Self::V {} = self;
+ let _ = Self::V {};
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/89
+pub mod issue89 {
+ #![allow(bare_trait_objects)]
+
+ use async_trait::async_trait;
+
+ #[async_trait]
+ trait Trait {
+ async fn f(&self);
+ }
+
+ #[async_trait]
+ impl Trait for Send + Sync {
+ async fn f(&self) {}
+ }
+
+ #[async_trait]
+ impl Trait for dyn Fn(i8) + Send + Sync {
+ async fn f(&self) {}
+ }
+
+ #[async_trait]
+ impl Trait for (dyn Fn(u8) + Send + Sync) {
+ async fn f(&self) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/92
+pub mod issue92 {
+ use async_trait::async_trait;
+
+ macro_rules! mac {
+ ($($tt:tt)*) => {
+ $($tt)*
+ };
+ }
+
+ pub struct Struct<T> {
+ _x: T,
+ }
+
+ impl<T> Struct<T> {
+ const ASSOCIATED1: &'static str = "1";
+ async fn associated1() {}
+ }
+
+ #[async_trait]
+ pub trait Trait
+ where
+ mac!(Self): Send,
+ {
+ const ASSOCIATED2: &'static str;
+ type Associated2;
+
+ #[allow(path_statements, clippy::let_underscore_future, clippy::no_effect)]
+ async fn associated2(&self) {
+ // trait items
+ mac!(let _: Self::Associated2;);
+ mac!(let _: <Self>::Associated2;);
+ mac!(let _: <Self as Trait>::Associated2;);
+ mac!(Self::ASSOCIATED2;);
+ mac!(<Self>::ASSOCIATED2;);
+ mac!(<Self as Trait>::ASSOCIATED2;);
+ mac!(let _ = Self::associated2(self););
+ mac!(let _ = <Self>::associated2(self););
+ mac!(let _ = <Self as Trait>::associated2(self););
+ }
+ }
+
+ #[async_trait]
+ impl<T: Send + Sync> Trait for Struct<T>
+ where
+ mac!(Self): Send,
+ {
+ const ASSOCIATED2: &'static str = "2";
+ type Associated2 = ();
+
+ #[allow(path_statements, clippy::let_underscore_future, clippy::no_effect)]
+ async fn associated2(&self) {
+ // inherent items
+ mac!(Self::ASSOCIATED1;);
+ mac!(<Self>::ASSOCIATED1;);
+ mac!(let _ = Self::associated1(););
+ mac!(let _ = <Self>::associated1(););
+
+ // trait items
+ mac!(let _: <Self as Trait>::Associated2;);
+ mac!(Self::ASSOCIATED2;);
+ mac!(<Self>::ASSOCIATED2;);
+ mac!(<Self as Trait>::ASSOCIATED2;);
+ mac!(let _ = Self::associated2(self););
+ mac!(let _ = <Self>::associated2(self););
+ mac!(let _ = <Self as Trait>::associated2(self););
+ }
+ }
+
+ pub struct Unit;
+
+ #[async_trait]
+ impl Trait for Unit {
+ const ASSOCIATED2: &'static str = "2";
+ type Associated2 = ();
+
+ async fn associated2(&self) {
+ mac!(let Self: Self = *self;);
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/92#issuecomment-683370136
+pub mod issue92_2 {
+ use async_trait::async_trait;
+
+ macro_rules! mac {
+ ($($tt:tt)*) => {
+ $($tt)*
+ };
+ }
+
+ pub trait Trait1 {
+ fn func1();
+ }
+
+ #[async_trait]
+ pub trait Trait2: Trait1 {
+ async fn func2() {
+ mac!(Self::func1());
+
+ macro_rules! mac2 {
+ ($($tt:tt)*) => {
+ Self::func1();
+ };
+ }
+ mac2!();
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/104
+pub mod issue104 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ trait T1 {
+ async fn id(&self) -> i32;
+ }
+
+ macro_rules! impl_t1 {
+ ($ty:ty, $id:expr) => {
+ #[async_trait]
+ impl T1 for $ty {
+ async fn id(&self) -> i32 {
+ $id
+ }
+ }
+ };
+ }
+
+ struct Foo;
+
+ impl_t1!(Foo, 1);
+}
+
+// https://github.com/dtolnay/async-trait/issues/106
+pub mod issue106 {
+ use async_trait::async_trait;
+ use std::future::Future;
+
+ #[async_trait]
+ pub trait ProcessPool: Send + Sync {
+ type ThreadPool;
+
+ async fn spawn<F, Fut, T>(&self, work: F) -> T
+ where
+ F: FnOnce(&Self::ThreadPool) -> Fut + Send,
+ Fut: Future<Output = T> + 'static;
+ }
+
+ #[async_trait]
+ impl<P> ProcessPool for &P
+ where
+ P: ?Sized + ProcessPool,
+ {
+ type ThreadPool = P::ThreadPool;
+
+ async fn spawn<F, Fut, T>(&self, work: F) -> T
+ where
+ F: FnOnce(&Self::ThreadPool) -> Fut + Send,
+ Fut: Future<Output = T> + 'static,
+ {
+ (**self).spawn(work).await
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/110
+pub mod issue110 {
+ use async_trait::async_trait;
+ use std::marker::PhantomData;
+
+ #[async_trait]
+ pub trait Loader {
+ async fn load(&self, key: &str);
+ }
+
+ pub struct AwsEc2MetadataLoader<'a> {
+ marker: PhantomData<&'a ()>,
+ }
+
+ #[async_trait]
+ impl Loader for AwsEc2MetadataLoader<'_> {
+ async fn load(&self, _key: &str) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/120
+pub mod issue120 {
+ #![deny(clippy::trivially_copy_pass_by_ref)]
+
+ use async_trait::async_trait;
+
+ #[async_trait]
+ trait Trait {
+ async fn f(&self);
+ }
+
+ #[async_trait]
+ impl Trait for () {
+ async fn f(&self) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/123
+pub mod issue123 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ trait Trait<T = ()> {
+ async fn f(&self) -> &str
+ where
+ T: 'async_trait,
+ {
+ "default"
+ }
+ }
+
+ #[async_trait]
+ impl<T> Trait<T> for () {}
+}
+
+// https://github.com/dtolnay/async-trait/issues/129
+pub mod issue129 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait TestTrait {
+ async fn a(_b: u8, c: u8) -> u8 {
+ c
+ }
+ }
+
+ pub struct TestStruct;
+
+ #[async_trait]
+ impl TestTrait for TestStruct {
+ async fn a(_b: u8, c: u8) -> u8 {
+ c
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/134
+#[cfg(async_trait_nightly_testing)]
+pub mod issue134 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ trait TestTrait {
+ async fn run<const DUMMY: bool>(self)
+ where
+ Self: Sized,
+ {
+ }
+ }
+
+ pub struct TestStruct;
+
+ #[async_trait]
+ impl TestTrait for TestStruct {
+ async fn run<const DUMMY: bool>(self)
+ where
+ Self: Sized,
+ {
+ }
+ }
+}
+
+// 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);
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/158
+pub mod issue158 {
+ use async_trait::async_trait;
+
+ fn f() {}
+
+ #[async_trait]
+ pub trait Trait {
+ async fn f(&self) {
+ self::f();
+ }
+ }
+}
+
+// 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<Self>);
+ }
+
+ pub struct MyStruct(bool);
+
+ #[async_trait]
+ impl Trait for MyStruct {
+ async fn f(self: Arc<Self>) {
+ futures::select! {
+ _ = async {
+ println!("{}", self.0);
+ }.fuse() => {}
+ }
+ }
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/169
+#[deny(where_clauses_object_safety)]
+pub mod issue169 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Trait: ::core::marker::Sync {
+ async fn f(&self) {}
+ }
+
+ pub fn test(_t: &dyn Trait) {}
+}
+
+// https://github.com/dtolnay/async-trait/issues/177
+pub mod issue177 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Trait {
+ async fn foo(&self, _callback: impl FnMut(&str) + Send) {}
+ }
+
+ pub struct Struct;
+
+ #[async_trait]
+ impl Trait for Struct {
+ async fn foo(&self, _callback: impl FnMut(&str) + Send) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/183
+pub mod issue183 {
+ #![deny(clippy::shadow_same)]
+
+ use async_trait::async_trait;
+
+ #[async_trait]
+ trait Foo {
+ async fn foo(_n: i32) {}
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/199
+pub mod issue199 {
+ use async_trait::async_trait;
+ use std::cell::Cell;
+
+ struct IncrementOnDrop<'a>(&'a Cell<usize>);
+
+ impl<'a> Drop for IncrementOnDrop<'a> {
+ fn drop(&mut self) {
+ self.0.set(self.0.get() + 1);
+ }
+ }
+
+ #[async_trait(?Send)]
+ trait Trait {
+ async fn f(counter: &Cell<usize>, arg: IncrementOnDrop<'_>);
+ }
+
+ struct Struct;
+
+ #[async_trait(?Send)]
+ impl Trait for Struct {
+ async fn f(counter: &Cell<usize>, _: IncrementOnDrop<'_>) {
+ assert_eq!(counter.get(), 0); // second arg not dropped yet
+ }
+ }
+
+ #[test]
+ fn test() {
+ let counter = Cell::new(0);
+ let future = Struct::f(&counter, IncrementOnDrop(&counter));
+ assert_eq!(counter.get(), 0);
+ drop(future);
+ assert_eq!(counter.get(), 1);
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/204
+pub mod issue204 {
+ use async_trait::async_trait;
+
+ #[async_trait]
+ pub trait Trait {
+ async fn f(arg: &impl Trait);
+ async fn g(arg: *const impl Trait);
+ }
+}
+
+// https://github.com/dtolnay/async-trait/issues/210
+pub mod issue210 {
+ use async_trait::async_trait;
+ use std::sync::Arc;
+
+ #[async_trait]
+ pub trait Trait {
+ async fn f(self: Arc<Self>) {}
+ }
+}
diff --git a/third_party/rust/async-trait/tests/ui/arg-implementation-detail.rs b/third_party/rust/async-trait/tests/ui/arg-implementation-detail.rs
new file mode 100644
index 0000000000..b83aa72fcf
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/arg-implementation-detail.rs
@@ -0,0 +1,22 @@
+use async_trait::async_trait;
+
+pub struct Struct;
+
+#[async_trait]
+pub trait Trait {
+ async fn f((_a, _b): (Struct, Struct)) {
+ // Expands to something like:
+ //
+ // fn f(__arg0: (Struct, Struct)) -> … {
+ // Box::pin(async move {
+ // let (_a, _b) = __arg0;
+ // …
+ // })
+ // }
+ //
+ // but user's code must not be allowed to name that temporary argument:
+ let _ = __arg0;
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/arg-implementation-detail.stderr b/third_party/rust/async-trait/tests/ui/arg-implementation-detail.stderr
new file mode 100644
index 0000000000..e742688888
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/arg-implementation-detail.stderr
@@ -0,0 +1,5 @@
+error[E0425]: cannot find value `__arg0` in this scope
+ --> tests/ui/arg-implementation-detail.rs:18:17
+ |
+18 | let _ = __arg0;
+ | ^^^^^^ not found in this scope
diff --git a/third_party/rust/async-trait/tests/ui/bare-trait-object.rs b/third_party/rust/async-trait/tests/ui/bare-trait-object.rs
new file mode 100644
index 0000000000..afcd6b44c3
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/bare-trait-object.rs
@@ -0,0 +1,15 @@
+#![deny(bare_trait_objects)]
+
+use async_trait::async_trait;
+
+#[async_trait]
+trait Trait {
+ async fn f(&self);
+}
+
+#[async_trait]
+impl Trait for Send + Sync {
+ async fn f(&self) {}
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/bare-trait-object.stderr b/third_party/rust/async-trait/tests/ui/bare-trait-object.stderr
new file mode 100644
index 0000000000..50b20484cb
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/bare-trait-object.stderr
@@ -0,0 +1,21 @@
+error: trait objects without an explicit `dyn` are deprecated
+ --> tests/ui/bare-trait-object.rs:11:16
+ |
+11 | impl Trait for Send + Sync {
+ | ^^^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+note: the lint level is defined here
+ --> tests/ui/bare-trait-object.rs:1:9
+ |
+1 | #![deny(bare_trait_objects)]
+ | ^^^^^^^^^^^^^^^^^^
+help: use `dyn`
+ |
+11 | impl Trait for dyn Send + Sync {
+ | +++
+help: alternatively use a blanket implementation to implement `Trait` for all types that also implement `Send + Sync`
+ |
+11 | impl<T: Send + Sync> Trait for T {
+ | ++++++++++++++++ ~
diff --git a/third_party/rust/async-trait/tests/ui/consider-restricting.rs b/third_party/rust/async-trait/tests/ui/consider-restricting.rs
new file mode 100644
index 0000000000..e23c8b1539
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/consider-restricting.rs
@@ -0,0 +1,26 @@
+// https://github.com/rust-lang/rust/issues/93828
+
+use async_trait::async_trait;
+
+pub trait IntoUrl {}
+
+#[async_trait]
+pub trait ClientExt {
+ async fn publish<T: IntoUrl>(&self, url: T);
+}
+
+struct Client;
+
+#[async_trait]
+impl ClientExt for Client {
+ async fn publish<T: IntoUrl>(&self, url: T) {}
+}
+
+struct Client2;
+
+#[async_trait]
+impl ClientExt for Client2 {
+ async fn publish<T>(&self, url: T) {}
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/consider-restricting.stderr b/third_party/rust/async-trait/tests/ui/consider-restricting.stderr
new file mode 100644
index 0000000000..62ff894ed5
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/consider-restricting.stderr
@@ -0,0 +1,33 @@
+error: future cannot be sent between threads safely
+ --> tests/ui/consider-restricting.rs:16:49
+ |
+16 | async fn publish<T: IntoUrl>(&self, url: T) {}
+ | ^^ future created by async block is not `Send`
+ |
+note: captured value is not `Send`
+ --> tests/ui/consider-restricting.rs:16:41
+ |
+16 | async fn publish<T: IntoUrl>(&self, url: T) {}
+ | ^^^ has type `T` which is not `Send`
+ = note: required for the cast from `[async block@$DIR/tests/ui/consider-restricting.rs:16:49: 16:51]` to the object type `dyn Future<Output = ()> + Send`
+help: consider further restricting this bound
+ |
+16 | async fn publish<T: IntoUrl + std::marker::Send>(&self, url: T) {}
+ | +++++++++++++++++++
+
+error: future cannot be sent between threads safely
+ --> tests/ui/consider-restricting.rs:23:40
+ |
+23 | async fn publish<T>(&self, url: T) {}
+ | ^^ future created by async block is not `Send`
+ |
+note: captured value is not `Send`
+ --> tests/ui/consider-restricting.rs:23:32
+ |
+23 | async fn publish<T>(&self, url: T) {}
+ | ^^^ has type `T` which is not `Send`
+ = note: required for the cast from `[async block@$DIR/tests/ui/consider-restricting.rs:23:40: 23:42]` to the object type `dyn Future<Output = ()> + Send`
+help: consider further restricting this bound
+ |
+23 | async fn publish<T + std::marker::Send>(&self, url: T) {}
+ | +++++++++++++++++++
diff --git a/third_party/rust/async-trait/tests/ui/delimiter-span.rs b/third_party/rust/async-trait/tests/ui/delimiter-span.rs
new file mode 100644
index 0000000000..51a44a24b5
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/delimiter-span.rs
@@ -0,0 +1,24 @@
+#![allow(unused_macro_rules)]
+
+use async_trait::async_trait;
+
+macro_rules! picky {
+ ($(t:tt)*) => {};
+}
+
+#[async_trait]
+trait Trait {
+ async fn method();
+}
+
+struct Struct;
+
+#[async_trait]
+impl Trait for Struct {
+ async fn method() {
+ picky!({ 123, self });
+ picky!({ 123 });
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/delimiter-span.stderr b/third_party/rust/async-trait/tests/ui/delimiter-span.stderr
new file mode 100644
index 0000000000..f03da4c97c
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/delimiter-span.stderr
@@ -0,0 +1,21 @@
+error: no rules expected the token `{`
+ --> tests/ui/delimiter-span.rs:19:16
+ |
+5 | macro_rules! picky {
+ | ------------------ when calling this macro
+...
+19 | picky!({ 123, self });
+ | ^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence start
+
+error: no rules expected the token `{`
+ --> tests/ui/delimiter-span.rs:20:16
+ |
+5 | macro_rules! picky {
+ | ------------------ when calling this macro
+...
+20 | picky!({ 123 });
+ | ^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence start
diff --git a/third_party/rust/async-trait/tests/ui/lifetime-span.rs b/third_party/rust/async-trait/tests/ui/lifetime-span.rs
new file mode 100644
index 0000000000..01981e6de4
--- /dev/null
+++ b/third_party/rust/async-trait/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/third_party/rust/async-trait/tests/ui/lifetime-span.stderr b/third_party/rust/async-trait/tests/ui/lifetime-span.stderr
new file mode 100644
index 0000000000..999da04c30
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/lifetime-span.stderr
@@ -0,0 +1,25 @@
+error[E0726]: implicit elided lifetime not allowed here
+ --> tests/ui/lifetime-span.rs:12:6
+ |
+12 | impl Trait for A {
+ | ^^^^^ expected lifetime parameter
+ |
+ = note: assuming a `'static` lifetime...
+help: indicate the anonymous lifetime
+ |
+12 | impl Trait<'_> for A {
+ | ++++
+
+error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+ --> tests/ui/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
+ --> tests/ui/lifetime-span.rs:22:11
+ |
+22 | pub trait Trait2 {
+ | ^^^^^^
diff --git a/third_party/rust/async-trait/tests/ui/missing-async-in-impl.rs b/third_party/rust/async-trait/tests/ui/missing-async-in-impl.rs
new file mode 100644
index 0000000000..3a5f58c3ac
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/missing-async-in-impl.rs
@@ -0,0 +1,15 @@
+use async_trait::async_trait;
+
+#[async_trait]
+pub trait Trait {
+ async fn method();
+}
+
+pub struct Struct;
+
+#[async_trait]
+impl Trait for Struct {
+ fn method() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/missing-async-in-impl.stderr b/third_party/rust/async-trait/tests/ui/missing-async-in-impl.stderr
new file mode 100644
index 0000000000..e461c85d8d
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/missing-async-in-impl.stderr
@@ -0,0 +1,8 @@
+error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration
+ --> tests/ui/missing-async-in-impl.rs:12:14
+ |
+5 | async fn method();
+ | -------- lifetimes in impl do not match this method in trait
+...
+12 | fn method() {}
+ | ^ lifetimes do not match method in trait
diff --git a/third_party/rust/async-trait/tests/ui/missing-async-in-trait.rs b/third_party/rust/async-trait/tests/ui/missing-async-in-trait.rs
new file mode 100644
index 0000000000..56fea7a1f8
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/missing-async-in-trait.rs
@@ -0,0 +1,15 @@
+use async_trait::async_trait;
+
+#[async_trait]
+pub trait Trait {
+ fn method();
+}
+
+pub struct Struct;
+
+#[async_trait]
+impl Trait for Struct {
+ async fn method() {}
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/missing-async-in-trait.stderr b/third_party/rust/async-trait/tests/ui/missing-async-in-trait.stderr
new file mode 100644
index 0000000000..c92c38da5e
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/missing-async-in-trait.stderr
@@ -0,0 +1,8 @@
+error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration
+ --> tests/ui/missing-async-in-trait.rs:12:14
+ |
+5 | fn method();
+ | - lifetimes in impl do not match this method in trait
+...
+12 | async fn method() {}
+ | ^^^^^^^^ lifetimes do not match method in trait
diff --git a/third_party/rust/async-trait/tests/ui/missing-body.rs b/third_party/rust/async-trait/tests/ui/missing-body.rs
new file mode 100644
index 0000000000..f3e1126d1d
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/missing-body.rs
@@ -0,0 +1,15 @@
+use async_trait::async_trait;
+
+#[async_trait]
+trait Trait {
+ async fn f(&self);
+}
+
+struct Thing;
+
+#[async_trait]
+impl Trait for Thing {
+ async fn f(&self);
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/missing-body.stderr b/third_party/rust/async-trait/tests/ui/missing-body.stderr
new file mode 100644
index 0000000000..e6ddb425f9
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/missing-body.stderr
@@ -0,0 +1,7 @@
+error: associated function in `impl` without body
+ --> tests/ui/missing-body.rs:12:5
+ |
+12 | async fn f(&self);
+ | ^^^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the function: `{ <body> }`
diff --git a/third_party/rust/async-trait/tests/ui/must-use.rs b/third_party/rust/async-trait/tests/ui/must-use.rs
new file mode 100644
index 0000000000..7ad0d9bf33
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/must-use.rs
@@ -0,0 +1,21 @@
+#![deny(unused_must_use)]
+
+use async_trait::async_trait;
+
+#[async_trait]
+trait Interface {
+ async fn f(&self);
+}
+
+struct Thing;
+
+#[async_trait]
+impl Interface for Thing {
+ async fn f(&self) {}
+}
+
+pub async fn f() {
+ Thing.f();
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/must-use.stderr b/third_party/rust/async-trait/tests/ui/must-use.stderr
new file mode 100644
index 0000000000..fd6fc31d60
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/must-use.stderr
@@ -0,0 +1,11 @@
+error: unused return value of `Interface::f` that must be used
+ --> tests/ui/must-use.rs:18:5
+ |
+18 | Thing.f();
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> tests/ui/must-use.rs:1:9
+ |
+1 | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
diff --git a/third_party/rust/async-trait/tests/ui/self-span.rs b/third_party/rust/async-trait/tests/ui/self-span.rs
new file mode 100644
index 0000000000..b01f247032
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/self-span.rs
@@ -0,0 +1,30 @@
+use async_trait::async_trait;
+
+pub struct S {}
+
+pub enum E {
+ V {},
+}
+
+#[async_trait]
+pub trait Trait {
+ async fn method(self);
+}
+
+#[async_trait]
+impl Trait for S {
+ async fn method(self) {
+ let _: () = self;
+ let _: Self = Self;
+ }
+}
+
+#[async_trait]
+impl Trait for E {
+ async fn method(self) {
+ let _: () = self;
+ let _: Self = Self::V;
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/self-span.stderr b/third_party/rust/async-trait/tests/ui/self-span.stderr
new file mode 100644
index 0000000000..8743e57934
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/self-span.stderr
@@ -0,0 +1,27 @@
+error[E0308]: mismatched types
+ --> tests/ui/self-span.rs:17:21
+ |
+17 | let _: () = self;
+ | -- ^^^^ expected `()`, found struct `S`
+ | |
+ | expected due to this
+
+error: the `Self` constructor can only be used with tuple or unit structs
+ --> tests/ui/self-span.rs:18:23
+ |
+18 | let _: Self = Self;
+ | ^^^^ help: use curly brackets: `Self { /* fields */ }`
+
+error[E0308]: mismatched types
+ --> tests/ui/self-span.rs:25:21
+ |
+25 | let _: () = self;
+ | -- ^^^^ expected `()`, found enum `E`
+ | |
+ | expected due to this
+
+error[E0533]: expected value, found struct variant `Self::V`
+ --> tests/ui/self-span.rs:26:23
+ |
+26 | let _: Self = Self::V;
+ | ^^^^^^^ not a value
diff --git a/third_party/rust/async-trait/tests/ui/send-not-implemented.rs b/third_party/rust/async-trait/tests/ui/send-not-implemented.rs
new file mode 100644
index 0000000000..d8883fb498
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/send-not-implemented.rs
@@ -0,0 +1,22 @@
+use async_trait::async_trait;
+use std::sync::Mutex;
+
+async fn f() {}
+
+#[async_trait]
+trait Test {
+ async fn test(&self) {
+ let mutex = Mutex::new(());
+ 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/third_party/rust/async-trait/tests/ui/send-not-implemented.stderr b/third_party/rust/async-trait/tests/ui/send-not-implemented.stderr
new file mode 100644
index 0000000000..d68fc43c36
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/send-not-implemented.stderr
@@ -0,0 +1,47 @@
+error: future cannot be sent between threads safely
+ --> tests/ui/send-not-implemented.rs:8:26
+ |
+8 | async fn test(&self) {
+ | __________________________^
+9 | | let mutex = Mutex::new(());
+10 | | let _guard = mutex.lock().unwrap();
+11 | | f().await;
+12 | | }
+ | |_____^ future created by async block is not `Send`
+ |
+ = help: within `[async block@$DIR/tests/ui/send-not-implemented.rs:8:26: 12:6]`, the trait `Send` is not implemented for `MutexGuard<'_, ()>`
+note: future is not `Send` as this value is used across an await
+ --> tests/ui/send-not-implemented.rs:11:12
+ |
+10 | let _guard = mutex.lock().unwrap();
+ | ------ has type `MutexGuard<'_, ()>` which is not `Send`
+11 | f().await;
+ | ^^^^^^ await occurs here, with `_guard` maybe used later
+12 | }
+ | - `_guard` is later dropped here
+ = note: required for the cast from `[async block@$DIR/tests/ui/send-not-implemented.rs:8:26: 12:6]` to the object type `dyn Future<Output = ()> + Send`
+
+error: future cannot be sent between threads safely
+ --> tests/ui/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 `[async block@$DIR/tests/ui/send-not-implemented.rs:14:38: 19:6]`, the trait `Send` is not implemented for `MutexGuard<'_, ()>`
+note: future is not `Send` as this value is used across an await
+ --> tests/ui/send-not-implemented.rs:17:12
+ |
+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 from `[async block@$DIR/tests/ui/send-not-implemented.rs:14:38: 19:6]` to the object type `dyn Future<Output = bool> + Send`
diff --git a/third_party/rust/async-trait/tests/ui/unreachable.rs b/third_party/rust/async-trait/tests/ui/unreachable.rs
new file mode 100644
index 0000000000..cac2826444
--- /dev/null
+++ b/third_party/rust/async-trait/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/third_party/rust/async-trait/tests/ui/unreachable.stderr b/third_party/rust/async-trait/tests/ui/unreachable.stderr
new file mode 100644
index 0000000000..08595e5af7
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/unreachable.stderr
@@ -0,0 +1,14 @@
+error: unreachable statement
+ --> tests/ui/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
+ --> tests/ui/unreachable.rs:1:9
+ |
+1 | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unreachable_code)]` implied by `#[deny(warnings)]`
diff --git a/third_party/rust/async-trait/tests/ui/unsupported-self.rs b/third_party/rust/async-trait/tests/ui/unsupported-self.rs
new file mode 100644
index 0000000000..5868c614ad
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/unsupported-self.rs
@@ -0,0 +1,15 @@
+use async_trait::async_trait;
+
+#[async_trait]
+pub trait Trait {
+ async fn method();
+}
+
+#[async_trait]
+impl Trait for &'static str {
+ async fn method() {
+ let _ = Self;
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/async-trait/tests/ui/unsupported-self.stderr b/third_party/rust/async-trait/tests/ui/unsupported-self.stderr
new file mode 100644
index 0000000000..14939459e1
--- /dev/null
+++ b/third_party/rust/async-trait/tests/ui/unsupported-self.stderr
@@ -0,0 +1,5 @@
+error: the `Self` constructor can only be used with tuple or unit structs
+ --> tests/ui/unsupported-self.rs:11:17
+ |
+11 | let _ = Self;
+ | ^^^^