diff --git a/src/lib.rs b/src/lib.rs index 1366b81..413e176 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,10 +115,10 @@ //! // Generic associated types, the return values are moved to here. //! // NOTE: all #[send] methods also get the `Send` trait bound. //! type OpenFuture<'a>: ::core::future::Future> + -//! ::core::marker::Send + 'a; -//! type ReadFuture<'a>: ::core::future::Future> + 'a; -//! type WriteFuture<'a>: ::core::future::Future> + 'a; -//! type CloseFuture<'a>: ::core::future::Future> + 'a; +//! ::core::marker::Send + 'a where Self: 'a; +//! type ReadFuture<'a>: ::core::future::Future> + 'a where Self: 'a; +//! type WriteFuture<'a>: ::core::future::Future> + 'a where Self: 'a; +//! type CloseFuture<'a>: ::core::future::Future> + 'a where Self: 'a; //! } //! ``` //! @@ -133,10 +133,10 @@ //! # fn read<'a>(&'a self, fd: FileDescriptor, buf: &'a mut [u8]) -> Self::ReadFuture<'a>; //! # fn write<'a>(&'a self, fd: FileDescriptor, buf: &'a [u8]) -> Self::WriteFuture<'a>; //! # fn close<'a>(&'a self, fd: FileDescriptor) -> Self::CloseFuture<'a>; -//! # type OpenFuture<'a>: ::core::future::Future> + Send + 'a; -//! # type ReadFuture<'a>: ::core::future::Future> + 'a; -//! # type WriteFuture<'a>: ::core::future::Future> + 'a; -//! # type CloseFuture<'a>: ::core::future::Future> + 'a; +//! # type OpenFuture<'a>: ::core::future::Future> + Send + 'a where Self: 'a; +//! # type ReadFuture<'a>: ::core::future::Future> + 'a where Self: 'a; +//! # type WriteFuture<'a>: ::core::future::Future> + 'a where Self: 'a; +//! # type CloseFuture<'a>: ::core::future::Future> + 'a where Self: 'a; //! # } //! # const ENOENT: Errno = Errno; //! # const EBADF: Errno = Errno; @@ -188,13 +188,15 @@ extern crate proc_macro; +use std::iter::FromIterator; use std::str::FromStr; use std::{iter, mem}; use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::punctuated::Punctuated; -use syn::token; +use syn::token::Where; +use syn::{token, PredicateType, WhereClause, WherePredicate}; use syn::{ AngleBracketedGenericArguments, AttrStyle, Attribute, Binding, Block, Expr, ExprAsync, FnArg, GenericArgument, GenericParam, Generics, Ident, ImplItem, ImplItemType, ItemImpl, ItemTrait, @@ -311,7 +313,32 @@ fn handle_item_impl(mut item: ItemImpl) -> TokenStream { generics: Generics { lt_token: Some(Token!(<)(Span::call_site())), gt_token: Some(Token!(>)(Span::call_site())), - where_clause: None, + where_clause: Some(WhereClause { + where_token: Where::default(), + predicates: function_lifetimes + .iter() + .cloned() + .map(|lifetimedef| { + WherePredicate::Type(PredicateType { + colon_token: Token!(:)(Span::call_site()), + lifetimes: None, + bounded_ty: Type::Path(TypePath { + qself: None, + path: Path { + leading_colon: None, + segments: Punctuated::from_iter([PathSegment { + ident: Ident::new("Self", Span::call_site()), + arguments: PathArguments::None, + }]), + }, + }), + bounds: Punctuated::from_iter([TypeParamBound::Lifetime( + lifetimedef.lifetime, + )]), + }) + }) + .collect(), + }), params: function_lifetimes .iter() .cloned() @@ -590,7 +617,32 @@ fn handle_item_trait(mut item: ItemTrait) -> TokenStream { generics: Generics { lt_token: Some(Token!(<)(Span::call_site())), gt_token: Some(Token!(>)(Span::call_site())), - where_clause: None, + where_clause: Some(WhereClause { + where_token: Where::default(), + predicates: function_lifetimes + .iter() + .cloned() + .map(|lifetimedef| { + WherePredicate::Type(PredicateType { + colon_token: Token!(:)(Span::call_site()), + lifetimes: None, + bounded_ty: Type::Path(TypePath { + qself: None, + path: Path { + leading_colon: None, + segments: Punctuated::from_iter([PathSegment { + ident: Ident::new("Self", Span::call_site()), + arguments: PathArguments::None, + }]), + }, + }), + bounds: Punctuated::from_iter([TypeParamBound::Lifetime( + lifetimedef.lifetime, + )]), + }) + }) + .collect(), + }), params: function_lifetimes .iter() .cloned() diff --git a/src/tests.rs b/src/tests.rs index 228529a..2b1b684 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -16,10 +16,10 @@ fn correct_trait_output() { fn write<'a>(&'a mut self, fd: usize, buf: &'a [u8]) -> Self::__real_async_trait_impl_TypeFor_write<'a>; fn close<'a>(&'a mut self, fd: usize) -> Self::__real_async_trait_impl_TypeFor_close<'a>; - type __real_async_trait_impl_TypeFor_open<'a>: ::core::future::Future> + ::core::marker::Send + 'a; - type __real_async_trait_impl_TypeFor_read<'a>: ::core::future::Future> + 'a; - type __real_async_trait_impl_TypeFor_write<'a>: ::core::future::Future> + 'a; - type __real_async_trait_impl_TypeFor_close<'a>: ::core::future::Future> + 'a; + type __real_async_trait_impl_TypeFor_open<'a>: ::core::future::Future> + ::core::marker::Send + 'a where Self: 'a; + type __real_async_trait_impl_TypeFor_read<'a>: ::core::future::Future> + 'a where Self: 'a; + type __real_async_trait_impl_TypeFor_write<'a>: ::core::future::Future> + 'a where Self: 'a; + type __real_async_trait_impl_TypeFor_close<'a>: ::core::future::Future> + 'a where Self: 'a; } }; let actual_output = crate::real_async_trait2(proc_macro2::TokenStream::new(), input); @@ -65,10 +65,10 @@ fn correct_impl_output() { async move { Ok(()) } } - type __real_async_trait_impl_TypeFor_open<'a> = __real_async_trait_impl_ExistentialTypeFor_open<'a>; - type __real_async_trait_impl_TypeFor_read<'a> = __real_async_trait_impl_ExistentialTypeFor_read<'a>; - type __real_async_trait_impl_TypeFor_write<'a> = __real_async_trait_impl_ExistentialTypeFor_write<'a>; - type __real_async_trait_impl_TypeFor_close<'a> = __real_async_trait_impl_ExistentialTypeFor_close<'a>; + type __real_async_trait_impl_TypeFor_open<'a> = __real_async_trait_impl_ExistentialTypeFor_open<'a> where Self: 'a; + type __real_async_trait_impl_TypeFor_read<'a> = __real_async_trait_impl_ExistentialTypeFor_read<'a> where Self: 'a; + type __real_async_trait_impl_TypeFor_write<'a> = __real_async_trait_impl_ExistentialTypeFor_write<'a> where Self: 'a; + type __real_async_trait_impl_TypeFor_close<'a> = __real_async_trait_impl_ExistentialTypeFor_close<'a> where Self: 'a; } type __real_async_trait_impl_ExistentialTypeFor_open<'a> = impl ::core::future::Future> + ::core::marker::Send + 'a; type __real_async_trait_impl_ExistentialTypeFor_read<'a> = impl ::core::future::Future> + 'a;