From c71ef5a5cc5a724586df1a0d0069c8ff5f16cc8b Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 30 May 2023 13:16:46 +0400 Subject: [PATCH] Use GATs in `Download` --- .github/workflows/ci.yml | 4 ++-- Cargo.toml | 2 +- README.md | 2 +- crates/teloxide-core/CHANGELOG.md | 3 +++ crates/teloxide-core/README.md | 2 +- .../teloxide-core/src/adaptors/auto_send.rs | 1 - crates/teloxide-core/src/adaptors/cache_me.rs | 1 - .../teloxide-core/src/adaptors/parse_mode.rs | 1 - .../src/adaptors/throttle/requester_impl.rs | 1 - crates/teloxide-core/src/bot/download.rs | 12 +++++----- crates/teloxide-core/src/lib.rs | 2 +- crates/teloxide-core/src/local_macros.rs | 22 +++++++++---------- crates/teloxide-core/src/net/download.rs | 19 +++++++++------- 13 files changed, 37 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 644ac35f..db70062f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ env: # - **/README.md # - **/src/lib.rs # - down below in a matrix - rust_msrv: 1.64.0 + rust_msrv: 1.65.0 CI: 1 @@ -91,7 +91,7 @@ jobs: toolchain: nightly-2023-05-28 features: "--features full nightly" - rust: msrv - toolchain: 1.64.0 + toolchain: 1.65.0 features: "--features full" steps: diff --git a/Cargo.toml b/Cargo.toml index 09124e33..9035d6ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ members = ["crates/*"] # The settings below will be applied to all crates in the workspace [workspace.package] # MSRV (minimal supported Rust version). -rust-version = "1.64" +rust-version = "1.65" edition = "2021" license = "MIT" diff --git a/README.md b/README.md index 49ab32db..1a778aa7 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ $ set TELOXIDE_TOKEN= $ $env:TELOXIDE_TOKEN= ``` - 4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.64): + 4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.65): ```bash # If you're using stable $ rustup update stable diff --git a/crates/teloxide-core/CHANGELOG.md b/crates/teloxide-core/CHANGELOG.md index f7545030..aac0f5d8 100644 --- a/crates/teloxide-core/CHANGELOG.md +++ b/crates/teloxide-core/CHANGELOG.md @@ -45,10 +45,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `RequestError::RetryAfter` single fields type to `Seconds` ([#859][pr859]) - `CallbackGame`, `ForumTopicClosed`, `ForumTopicReopened`, `GeneralForumTopicHidden`, `GeneralForumTopicUnhidden` and `WriteAccessAllowed` structures are now defined as named (`struct S {}`) instead of unit (`struct S;`) in order to fix their deserialization ([#876][pr876]) +- `Download` now uses GAT feature on the `Fut` and `Err` associated types, instead of a lifetime on the whole trait ([#885][pr885]) +- MSRV (Minimal Supported Rust Version) was bumped from `1.64.0` to `1.65.0` [pr852]: https://github.com/teloxide/teloxide/pull/853 [pr859]: https://github.com/teloxide/teloxide/pull/859 [pr876]: https://github.com/teloxide/teloxide/pull/876 +[pr885]: https://github.com/teloxide/teloxide/pull/885 ### Deprecated diff --git a/crates/teloxide-core/README.md b/crates/teloxide-core/README.md index 773c3709..bee0e8f6 100644 --- a/crates/teloxide-core/README.md +++ b/crates/teloxide-core/README.md @@ -27,7 +27,7 @@ ```toml teloxide-core = "0.9" ``` -_Compiler support: requires rustc 1.64+_. +_Compiler support: requires rustc 1.65+_. [`teloxide`]: https://docs.rs/teloxide [Telegram Bot API]: https://core.telegram.org/bots/api diff --git a/crates/teloxide-core/src/adaptors/auto_send.rs b/crates/teloxide-core/src/adaptors/auto_send.rs index a613d486..f72a6e1b 100644 --- a/crates/teloxide-core/src/adaptors/auto_send.rs +++ b/crates/teloxide-core/src/adaptors/auto_send.rs @@ -177,7 +177,6 @@ where } download_forward! { - 'w B AutoSend { this => this.inner() } diff --git a/crates/teloxide-core/src/adaptors/cache_me.rs b/crates/teloxide-core/src/adaptors/cache_me.rs index ae940f37..e34cb694 100644 --- a/crates/teloxide-core/src/adaptors/cache_me.rs +++ b/crates/teloxide-core/src/adaptors/cache_me.rs @@ -201,7 +201,6 @@ where } download_forward! { - 'w B CacheMe { this => this.inner() } diff --git a/crates/teloxide-core/src/adaptors/parse_mode.rs b/crates/teloxide-core/src/adaptors/parse_mode.rs index 1d915c9a..94d923d4 100644 --- a/crates/teloxide-core/src/adaptors/parse_mode.rs +++ b/crates/teloxide-core/src/adaptors/parse_mode.rs @@ -196,7 +196,6 @@ impl Requester for DefaultParseMode { } download_forward! { - 'w B DefaultParseMode { this => this.inner() } diff --git a/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs b/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs index 02b747e7..b48ce1a7 100644 --- a/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs +++ b/crates/teloxide-core/src/adaptors/throttle/requester_impl.rs @@ -182,7 +182,6 @@ where } download_forward! { - 'w B Throttle { this => this.inner() } diff --git a/crates/teloxide-core/src/bot/download.rs b/crates/teloxide-core/src/bot/download.rs index 4b07460b..8e224a6d 100644 --- a/crates/teloxide-core/src/bot/download.rs +++ b/crates/teloxide-core/src/bot/download.rs @@ -8,18 +8,18 @@ use crate::{ DownloadError, }; -impl<'w> Download<'w> for Bot { - type Err = DownloadError; +impl Download for Bot { + type Err<'dst> = DownloadError; // I would like to unbox this, but my coworkers will kill me if they'll see yet // another hand written `Future`. (waffle) - type Fut = BoxFuture<'w, Result<(), Self::Err>>; + type Fut<'dst> = BoxFuture<'dst, Result<(), Self::Err<'dst>>>; - fn download_file( + fn download_file<'dst>( &self, path: &str, - destination: &'w mut (dyn AsyncWrite + Unpin + Send), - ) -> Self::Fut { + destination: &'dst mut (dyn AsyncWrite + Unpin + Send), + ) -> Self::Fut<'dst> { net::download_file( &self.client, reqwest::Url::clone(&*self.api_url), diff --git a/crates/teloxide-core/src/lib.rs b/crates/teloxide-core/src/lib.rs index 6127ad54..2ed0e14f 100644 --- a/crates/teloxide-core/src/lib.rs +++ b/crates/teloxide-core/src/lib.rs @@ -7,7 +7,7 @@ //!```toml //! teloxide_core = "0.9" //! ``` -//! _Compiler support: requires rustc 1.64+_. +//! _Compiler support: requires rustc 1.65+_. //! //! ``` //! # async { diff --git a/crates/teloxide-core/src/local_macros.rs b/crates/teloxide-core/src/local_macros.rs index c0c6e51c..18b4a103 100644 --- a/crates/teloxide-core/src/local_macros.rs +++ b/crates/teloxide-core/src/local_macros.rs @@ -372,26 +372,26 @@ macro_rules! impl_payload { } macro_rules! download_forward { - ($l:lifetime $T:ident $S:ty {$this:ident => $inner:expr}) => { - impl<$l, $T: $crate::net::Download<$l>> $crate::net::Download<$l> for $S { - type Err = <$T as $crate::net::Download<$l>>::Err; + ($T:ident $S:ty {$this:ident => $inner:expr}) => { + impl<$T: $crate::net::Download> $crate::net::Download for $S { + type Err<'dst> = <$T as $crate::net::Download>::Err<'dst>; - type Fut = <$T as $crate::net::Download<$l>>::Fut; + type Fut<'dst> = <$T as $crate::net::Download>::Fut<'dst>; - fn download_file( + fn download_file<'dst>( &self, path: &str, - destination: &'w mut (dyn tokio::io::AsyncWrite - + core::marker::Unpin - + core::marker::Send), - ) -> Self::Fut { + destination: &'dst mut (dyn tokio::io::AsyncWrite + + core::marker::Unpin + + core::marker::Send), + ) -> Self::Fut<'dst> { let $this = self; ($inner).download_file(path, destination) } - type StreamErr = <$T as $crate::net::Download<$l>>::StreamErr; + type StreamErr = <$T as $crate::net::Download>::StreamErr; - type Stream = <$T as $crate::net::Download<$l>>::Stream; + type Stream = <$T as $crate::net::Download>::Stream; fn download_file_stream(&self, path: &str) -> Self::Stream { let $this = self; diff --git a/crates/teloxide-core/src/net/download.rs b/crates/teloxide-core/src/net/download.rs index 338fd547..3a6ea43a 100644 --- a/crates/teloxide-core/src/net/download.rs +++ b/crates/teloxide-core/src/net/download.rs @@ -12,14 +12,17 @@ use tokio::io::{AsyncWrite, AsyncWriteExt}; use crate::{errors::DownloadError, net::file_url}; /// A trait for downloading files from Telegram. -// FIXME(waffle): ideally, this lifetime ('w) shouldn't be here, but we can't -// help it without GATs -pub trait Download<'w> { +pub trait Download { /// An error returned from [`download_file`](Self::download_file). - type Err; + type Err<'dst>; /// A future returned from [`download_file`](Self::download_file). - type Fut: Future> + Send; + type Fut<'dst>: Future>> + Send; + + // NOTE: We currently only allow borrowing `dst` in the future, + // however we could also allow borrowing `self` or `path`. + // This doesn't seem useful for our current implementers of + // `Download`, but we could. /// Download a file from Telegram into `destination`. /// @@ -49,11 +52,11 @@ pub trait Download<'w> { /// /// [`GetFile`]: crate::payloads::GetFile /// [`download_file_stream`]: Self::download_file_stream - fn download_file( + fn download_file<'dst>( &self, path: &str, - destination: &'w mut (dyn AsyncWrite + Unpin + Send), - ) -> Self::Fut; + destination: &'dst mut (dyn AsyncWrite + Unpin + Send), + ) -> Self::Fut<'dst>; /// An error returned from /// [`download_file_stream`](Self::download_file_stream).