blob: db065a9cd8a3fbe16c88afcbdb4978ac8759715d [file] [log] [blame]
#![cfg_attr(async_trait_nightly_testing, feature(specialization, const_generics))]
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 {}
// 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/46
pub mod issue46 {
use async_trait::async_trait;
macro_rules! implement_commands {
($tyargs:tt : $ty:tt) => {
#[async_trait]
pub trait AsyncCommands: 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);
}
}