From 483f23176ab1dff362eaa6f605694648d894d9d5 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Tue, 6 May 2025 13:17:32 -0400 Subject: [PATCH 1/7] macro-body async impl --- Cargo.toml | 1 + src/client/session/action.rs | 126 +++++++++++++++++++--------------- src/test/spec/transactions.rs | 33 +++++++++ 3 files changed, 105 insertions(+), 55 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0f4afc981..b612f8998 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,6 +118,7 @@ typed-builder = "0.20.0" webpki-roots = "0.26" zstd = { version = "0.11.2", optional = true } macro_magic = "0.5.1" +rustversion = "1.0.20" [dependencies.pbkdf2] version = "0.11.0" diff --git a/src/client/session/action.rs b/src/client/session/action.rs index 7be9a1047..ba775a20f 100644 --- a/src/client/session/action.rs +++ b/src/client/session/action.rs @@ -99,6 +99,68 @@ impl<'a> Action for StartTransaction<&'a mut ClientSession> { } } +macro_rules! convenient_run { + ($self:ident, $callback:expr) => {{ + let timeout = Duration::from_secs(120); + #[cfg(test)] + let timeout = $self + .session + .convenient_transaction_timeout + .unwrap_or(timeout); + let start = Instant::now(); + + use crate::error::{TRANSIENT_TRANSACTION_ERROR, UNKNOWN_TRANSACTION_COMMIT_RESULT}; + + 'transaction: loop { + $self + .session + .start_transaction() + .with_options($self.options.clone()) + .await?; + let ret = match $callback { + Ok(v) => v, + Err(e) => { + if matches!( + $self.session.transaction.state, + TransactionState::Starting | TransactionState::InProgress + ) { + $self.session.abort_transaction().await?; + } + if e.contains_label(TRANSIENT_TRANSACTION_ERROR) && start.elapsed() < timeout { + continue 'transaction; + } + return Err(e); + } + }; + if matches!( + $self.session.transaction.state, + TransactionState::None + | TransactionState::Aborted + | TransactionState::Committed { .. } + ) { + return Ok(ret); + } + 'commit: loop { + match $self.session.commit_transaction().await { + Ok(()) => return Ok(ret), + Err(e) => { + if e.is_max_time_ms_expired_error() || start.elapsed() >= timeout { + return Err(e); + } + if e.contains_label(UNKNOWN_TRANSACTION_COMMIT_RESULT) { + continue 'commit; + } + if e.contains_label(TRANSIENT_TRANSACTION_ERROR) { + continue 'transaction; + } + return Err(e); + } + } + } + } + }}; +} + impl StartTransaction<&mut ClientSession> { /// Starts a transaction, runs the given callback, and commits or aborts the transaction. /// Transient transaction errors will cause the callback or the commit to be retried; @@ -150,62 +212,16 @@ impl StartTransaction<&mut ClientSession> { where F: for<'b> FnMut(&'b mut ClientSession, &'b mut C) -> BoxFuture<'b, Result>, { - let timeout = Duration::from_secs(120); - #[cfg(test)] - let timeout = self - .session - .convenient_transaction_timeout - .unwrap_or(timeout); - let start = Instant::now(); - - use crate::error::{TRANSIENT_TRANSACTION_ERROR, UNKNOWN_TRANSACTION_COMMIT_RESULT}; + convenient_run!(self, callback(self.session, &mut context).await) + } - 'transaction: loop { - self.session - .start_transaction() - .with_options(self.options.clone()) - .await?; - let ret = match callback(self.session, &mut context).await { - Ok(v) => v, - Err(e) => { - if matches!( - self.session.transaction.state, - TransactionState::Starting | TransactionState::InProgress - ) { - self.session.abort_transaction().await?; - } - if e.contains_label(TRANSIENT_TRANSACTION_ERROR) && start.elapsed() < timeout { - continue 'transaction; - } - return Err(e); - } - }; - if matches!( - self.session.transaction.state, - TransactionState::None - | TransactionState::Aborted - | TransactionState::Committed { .. } - ) { - return Ok(ret); - } - 'commit: loop { - match self.session.commit_transaction().await { - Ok(()) => return Ok(ret), - Err(e) => { - if e.is_max_time_ms_expired_error() || start.elapsed() >= timeout { - return Err(e); - } - if e.contains_label(UNKNOWN_TRANSACTION_COMMIT_RESULT) { - continue 'commit; - } - if e.contains_label(TRANSIENT_TRANSACTION_ERROR) { - continue 'transaction; - } - return Err(e); - } - } - } - } + /// TODO + #[rustversion::since(1.85)] + pub async fn and_run2(self, mut callback: F) -> Result + where + F: for<'b> AsyncFnMut(&'b mut ClientSession) -> Result, + { + convenient_run!(self, callback(self.session).await) } } diff --git a/src/test/spec/transactions.rs b/src/test/spec/transactions.rs index d1b4a1901..866e94983 100644 --- a/src/test/spec/transactions.rs +++ b/src/test/spec/transactions.rs @@ -264,3 +264,36 @@ async fn convenient_api_retry_timeout_commit_transient() { let err = result.unwrap_err(); assert!(err.contains_label(TRANSIENT_TRANSACTION_ERROR)); } + +#[tokio::test] +async fn context() { + let client = Client::for_test().await; + let mut session = client.start_session().await.unwrap(); + let coll = client + .database("test_convenient") + .collection::("test_convenient"); + let my_data = "my data".to_string(); + /* + session + .start_transaction() + .and_run((), |session, _| { + async move { + coll.insert_one(doc! { "data": my_data }) + .session(session) + .await + } + .boxed() + }) + .await + .unwrap(); + */ + session + .start_transaction() + .and_run2(async move |session| { + coll.insert_one(doc! { "data": my_data.clone() }) + .session(session) + .await + }) + .await + .unwrap(); +} From 843faac108c8f45faaa68280e9917a640bcfa81f Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Wed, 7 May 2025 11:20:28 -0400 Subject: [PATCH 2/7] threeway macro --- src/client/session/action.rs | 147 +++++++++++++++++++--------------- src/test/spec/transactions.rs | 33 -------- 2 files changed, 82 insertions(+), 98 deletions(-) diff --git a/src/client/session/action.rs b/src/client/session/action.rs index ba775a20f..f7bc21acb 100644 --- a/src/client/session/action.rs +++ b/src/client/session/action.rs @@ -100,31 +100,30 @@ impl<'a> Action for StartTransaction<&'a mut ClientSession> { } macro_rules! convenient_run { - ($self:ident, $callback:expr) => {{ + ( + $session:expr, + $start_transaction:expr, + $callback:expr, + $abort_transaction:expr, + $commit_transaction:expr, + ) => {{ let timeout = Duration::from_secs(120); #[cfg(test)] - let timeout = $self - .session - .convenient_transaction_timeout - .unwrap_or(timeout); + let timeout = $session.convenient_transaction_timeout.unwrap_or(timeout); let start = Instant::now(); use crate::error::{TRANSIENT_TRANSACTION_ERROR, UNKNOWN_TRANSACTION_COMMIT_RESULT}; 'transaction: loop { - $self - .session - .start_transaction() - .with_options($self.options.clone()) - .await?; + $start_transaction?; let ret = match $callback { Ok(v) => v, Err(e) => { if matches!( - $self.session.transaction.state, + $session.transaction.state, TransactionState::Starting | TransactionState::InProgress ) { - $self.session.abort_transaction().await?; + $abort_transaction?; } if e.contains_label(TRANSIENT_TRANSACTION_ERROR) && start.elapsed() < timeout { continue 'transaction; @@ -133,7 +132,7 @@ macro_rules! convenient_run { } }; if matches!( - $self.session.transaction.state, + $session.transaction.state, TransactionState::None | TransactionState::Aborted | TransactionState::Committed { .. } @@ -141,7 +140,7 @@ macro_rules! convenient_run { return Ok(ret); } 'commit: loop { - match $self.session.commit_transaction().await { + match $commit_transaction { Ok(()) => return Ok(ret), Err(e) => { if e.is_max_time_ms_expired_error() || start.elapsed() >= timeout { @@ -212,16 +211,75 @@ impl StartTransaction<&mut ClientSession> { where F: for<'b> FnMut(&'b mut ClientSession, &'b mut C) -> BoxFuture<'b, Result>, { - convenient_run!(self, callback(self.session, &mut context).await) + convenient_run!( + self.session, + self.session + .start_transaction() + .with_options(self.options.clone()) + .await, + callback(self.session, &mut context).await, + self.session.abort_transaction().await, + self.session.commit_transaction().await, + ) } - /// TODO + /// Starts a transaction, runs the given callback, and commits or aborts the transaction. + /// Transient transaction errors will cause the callback or the commit to be retried; + /// other errors will cause the transaction to be aborted and the error returned to the + /// caller. If the callback needs to provide its own error information, the + /// [`Error::custom`](crate::error::Error::custom) method can accept an arbitrary payload that + /// can be retrieved via [`Error::get_custom`](crate::error::Error::get_custom). + /// + /// If a command inside the callback fails, it may cause the transaction on the server to be + /// aborted. This situation is normally handled transparently by the driver. However, if the + /// application does not return that error from the callback, the driver will not be able to + /// determine whether the transaction was aborted or not. The driver will then retry the + /// callback indefinitely. To avoid this situation, the application MUST NOT silently handle + /// errors within the callback. If the application needs to handle errors within the + /// callback, it MUST return them after doing so. + /// + /// Because the callback can be repeatedly executed, code within the callback cannot consume + /// owned values, even values owned by the callback itself: + /// + /// ```no_run + /// # use mongodb::{bson::{doc, Document}, error::Result, Client}; + /// # use futures::FutureExt; + /// # async fn wrapper() -> Result<()> { + /// # let client = Client::with_uri_str("mongodb://example.com").await?; + /// # let mut session = client.start_session().await?; + /// let coll = client.database("mydb").collection::("mycoll"); + /// let my_data = "my data".to_string(); + /// // This works: + /// session.start_transaction().and_run2( + /// async move |session| { + /// coll.insert_one(doc! { "data": my_data.clone() }).session(session).await + /// } + /// ).await?; + /// /* This will not compile: + /// session.start_transaction().and_run2( + /// async move |session| { + /// coll.insert_one(doc! { "data": my_data }).session(session).await + /// } + /// ).await?; + /// */ + /// # Ok(()) + /// # } + /// ``` #[rustversion::since(1.85)] pub async fn and_run2(self, mut callback: F) -> Result where F: for<'b> AsyncFnMut(&'b mut ClientSession) -> Result, { - convenient_run!(self, callback(self.session).await) + convenient_run!( + self.session, + self.session + .start_transaction() + .with_options(self.options.clone()) + .await, + callback(self.session).await, + self.session.abort_transaction().await, + self.session.commit_transaction().await, + ) } } @@ -254,57 +312,16 @@ impl StartTransaction<&mut crate::sync::ClientSession> { where F: for<'b> FnMut(&'b mut crate::sync::ClientSession) -> Result, { - let timeout = std::time::Duration::from_secs(120); - let start = std::time::Instant::now(); - - use crate::error::{TRANSIENT_TRANSACTION_ERROR, UNKNOWN_TRANSACTION_COMMIT_RESULT}; - - 'transaction: loop { + convenient_run!( + self.session.async_client_session, self.session .start_transaction() .with_options(self.options.clone()) - .run()?; - let ret = match callback(self.session) { - Ok(v) => v, - Err(e) => { - if matches!( - self.session.async_client_session.transaction.state, - TransactionState::Starting | TransactionState::InProgress - ) { - self.session.abort_transaction().run()?; - } - if e.contains_label(TRANSIENT_TRANSACTION_ERROR) && start.elapsed() < timeout { - continue 'transaction; - } - return Err(e); - } - }; - if matches!( - self.session.async_client_session.transaction.state, - TransactionState::None - | TransactionState::Aborted - | TransactionState::Committed { .. } - ) { - return Ok(ret); - } - 'commit: loop { - match self.session.commit_transaction().run() { - Ok(()) => return Ok(ret), - Err(e) => { - if e.is_max_time_ms_expired_error() || start.elapsed() >= timeout { - return Err(e); - } - if e.contains_label(UNKNOWN_TRANSACTION_COMMIT_RESULT) { - continue 'commit; - } - if e.contains_label(TRANSIENT_TRANSACTION_ERROR) { - continue 'transaction; - } - return Err(e); - } - } - } - } + .run(), + callback(self.session), + self.session.abort_transaction().run(), + self.session.commit_transaction().run(), + ) } } diff --git a/src/test/spec/transactions.rs b/src/test/spec/transactions.rs index 866e94983..d1b4a1901 100644 --- a/src/test/spec/transactions.rs +++ b/src/test/spec/transactions.rs @@ -264,36 +264,3 @@ async fn convenient_api_retry_timeout_commit_transient() { let err = result.unwrap_err(); assert!(err.contains_label(TRANSIENT_TRANSACTION_ERROR)); } - -#[tokio::test] -async fn context() { - let client = Client::for_test().await; - let mut session = client.start_session().await.unwrap(); - let coll = client - .database("test_convenient") - .collection::("test_convenient"); - let my_data = "my data".to_string(); - /* - session - .start_transaction() - .and_run((), |session, _| { - async move { - coll.insert_one(doc! { "data": my_data }) - .session(session) - .await - } - .boxed() - }) - .await - .unwrap(); - */ - session - .start_transaction() - .and_run2(async move |session| { - coll.insert_one(doc! { "data": my_data.clone() }) - .session(session) - .await - }) - .await - .unwrap(); -} From 7bb1ff83a3463679b3fa19529fcbffecadd22f97 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 8 May 2025 14:06:57 -0400 Subject: [PATCH 3/7] update most callers --- src/client/session/action.rs | 13 ++++- src/test/documentation_examples.rs | 8 +-- src/test/spec/transactions.rs | 50 +++++++------------ src/test/spec/unified_runner/operation.rs | 2 +- .../unified_runner/operation/transaction.rs | 2 + src/test/spec/v2_runner/operation.rs | 2 + 6 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/client/session/action.rs b/src/client/session/action.rs index f7bc21acb..e0d61c5a2 100644 --- a/src/client/session/action.rs +++ b/src/client/session/action.rs @@ -207,6 +207,7 @@ impl StartTransaction<&mut ClientSession> { /// # Ok(()) /// # } /// ``` + #[rustversion::attr(since(1.85), deprecated = "use and_run2")] pub async fn and_run(self, mut context: C, mut callback: F) -> Result where F: for<'b> FnMut(&'b mut ClientSession, &'b mut C) -> BoxFuture<'b, Result>, @@ -238,6 +239,10 @@ impl StartTransaction<&mut ClientSession> { /// errors within the callback. If the application needs to handle errors within the /// callback, it MUST return them after doing so. /// + /// This version of the method uses an async closure, which means it's both more convenient and + /// avoids the lifetime issues of `and_run`, but is only available in Rust versions 1.85 and + /// above. + /// /// Because the callback can be repeatedly executed, code within the callback cannot consume /// owned values, even values owned by the callback itself: /// @@ -266,10 +271,14 @@ impl StartTransaction<&mut ClientSession> { /// # } /// ``` #[rustversion::since(1.85)] - pub async fn and_run2(self, mut callback: F) -> Result + pub async fn and_run2( + self, + mut callback: impl AsyncFnMut(&mut ClientSession) -> Result, + ) -> Result +/* where F: for<'b> AsyncFnMut(&'b mut ClientSession) -> Result, - { + */ { convenient_run!( self.session, self.session diff --git a/src/test/documentation_examples.rs b/src/test/documentation_examples.rs index 069814ced..7f270171a 100644 --- a/src/test/documentation_examples.rs +++ b/src/test/documentation_examples.rs @@ -1675,7 +1675,6 @@ async fn change_streams_examples() -> Result<()> { async fn convenient_transaction_examples() -> Result<()> { use crate::ClientSession; - use futures::FutureExt; if !transactions_supported().await { log_uncaptured( "skipping convenient transaction API examples due to no transaction support", @@ -1734,12 +1733,9 @@ async fn convenient_transaction_examples() -> Result<()> { // Step 2: Start a client session. let mut session = client.start_session().await?; - // Step 3: Use and_run to start a transaction, execute the callback, and commit (or + // Step 3: Use and_run2 to start a transaction, execute the callback, and commit (or // abort on error). - session - .start_transaction() - .and_run((), |session, _| callback(session).boxed()) - .await?; + session.start_transaction().and_run2(callback).await?; // End Transactions withTxn API Example 1 diff --git a/src/test/spec/transactions.rs b/src/test/spec/transactions.rs index d1b4a1901..1e1108433 100644 --- a/src/test/spec/transactions.rs +++ b/src/test/spec/transactions.rs @@ -1,6 +1,5 @@ use std::time::Duration; -use futures_util::FutureExt; use serde::{Deserialize, Serialize}; use crate::{ @@ -104,12 +103,9 @@ async fn convenient_api_custom_error() { struct MyErr; let result: Result<()> = session .start_transaction() - .and_run(coll, |session, coll| { - async move { - coll.find_one(doc! {}).session(session).await?; - Err(Error::custom(MyErr)) - } - .boxed() + .and_run2(async move |session| { + coll.find_one(doc! {}).session(session).await?; + Err(Error::custom(MyErr)) }) .await; @@ -136,12 +132,9 @@ async fn convenient_api_returned_value() { let value = session .start_transaction() - .and_run(coll, |session, coll| { - async move { - coll.find_one(doc! {}).session(session).await?; - Ok(42) - } - .boxed() + .and_run2(async move |session| { + coll.find_one(doc! {}).session(session).await?; + Ok(42) }) .await .unwrap(); @@ -165,14 +158,11 @@ async fn convenient_api_retry_timeout_callback() { let result: Result<()> = session .start_transaction() - .and_run(coll, |session, coll| { - async move { - coll.find_one(doc! {}).session(session).await?; - let mut err = Error::custom(42); - err.add_label(TRANSIENT_TRANSACTION_ERROR); - Err(err) - } - .boxed() + .and_run2(async move |session| { + coll.find_one(doc! {}).session(session).await?; + let mut err = Error::custom(42); + err.add_label(TRANSIENT_TRANSACTION_ERROR); + Err(err) }) .await; @@ -210,12 +200,9 @@ async fn convenient_api_retry_timeout_commit_unknown() { let result = session .start_transaction() - .and_run(coll, |session, coll| { - async move { - coll.find_one(doc! {}).session(session).await?; - Ok(()) - } - .boxed() + .and_run2(async move |session| { + coll.find_one(doc! {}).session(session).await?; + Ok(()) }) .await; @@ -252,12 +239,9 @@ async fn convenient_api_retry_timeout_commit_transient() { let result = session .start_transaction() - .and_run(coll, |session, coll| { - async move { - coll.find_one(doc! {}).session(session).await?; - Ok(()) - } - .boxed() + .and_run2(async move |session| { + coll.find_one(doc! {}).session(session).await?; + Ok(()) }) .await; diff --git a/src/test/spec/unified_runner/operation.rs b/src/test/spec/unified_runner/operation.rs index 82e2bcd45..a823f88fd 100644 --- a/src/test/spec/unified_runner/operation.rs +++ b/src/test/spec/unified_runner/operation.rs @@ -157,7 +157,7 @@ pub(crate) trait TestOperation: Debug + Send + Sync { /// so that we can continue to borrow the entity map in other ways even when we're using a session, /// which we'd have to borrow mutably from the map. macro_rules! with_mut_session { - ($test_runner:ident, $id:expr, |$session:ident| $body:expr) => { + ($test_runner:expr, $id:expr, |$session:ident| $body:expr) => { async { let id = $id; let entity = $test_runner.entities.write().await.remove(id).unwrap(); diff --git a/src/test/spec/unified_runner/operation/transaction.rs b/src/test/spec/unified_runner/operation/transaction.rs index 5927dacc9..87f7dc7a4 100644 --- a/src/test/spec/unified_runner/operation/transaction.rs +++ b/src/test/spec/unified_runner/operation/transaction.rs @@ -100,6 +100,8 @@ impl TestOperation for WithTransaction { ) -> BoxFuture<'a, Result>> { async move { with_mut_session!(test_runner, id, |session| async move { + // `and_run2` runs afoul of a rustc bug here: https://github.com/rust-lang/rust/issues/64552 + #[allow(deprecated)] session .start_transaction() .with_options(self.options.clone()) diff --git a/src/test/spec/v2_runner/operation.rs b/src/test/spec/v2_runner/operation.rs index 8f19b3d88..40cf25c0f 100644 --- a/src/test/spec/v2_runner/operation.rs +++ b/src/test/spec/v2_runner/operation.rs @@ -1420,6 +1420,8 @@ impl TestOperation for WithTransaction { ) -> BoxFuture<'a, Result>> { async move { let session = sessions.session0.unwrap(); + // `and_run2` runs afoul of a rustc bug here: https://github.com/rust-lang/rust/issues/64552 + #[allow(deprecated)] session .start_transaction() .with_options(self.options.clone()) From e7c4a8c7b39fd7e0736215c5c67c19e4636eb280 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 8 May 2025 14:11:21 -0400 Subject: [PATCH 4/7] remove old comment --- Cargo.lock | 1 + src/client/session/action.rs | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f38f58d3..9a89e9fac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1567,6 +1567,7 @@ dependencies = [ "reqwest", "rustc_version_runtime", "rustls", + "rustversion", "semver", "serde", "serde-hex", diff --git a/src/client/session/action.rs b/src/client/session/action.rs index e0d61c5a2..d579b65fc 100644 --- a/src/client/session/action.rs +++ b/src/client/session/action.rs @@ -274,11 +274,7 @@ impl StartTransaction<&mut ClientSession> { pub async fn and_run2( self, mut callback: impl AsyncFnMut(&mut ClientSession) -> Result, - ) -> Result -/* - where - F: for<'b> AsyncFnMut(&'b mut ClientSession) -> Result, - */ { + ) -> Result { convenient_run!( self.session, self.session From 1cd00ab1611e7f53cab13aac179af89351fd9a13 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 8 May 2025 14:19:35 -0400 Subject: [PATCH 5/7] ensure closure lifetime is higher-ranked --- src/client/session/action.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client/session/action.rs b/src/client/session/action.rs index d579b65fc..c480e0829 100644 --- a/src/client/session/action.rs +++ b/src/client/session/action.rs @@ -271,10 +271,10 @@ impl StartTransaction<&mut ClientSession> { /// # } /// ``` #[rustversion::since(1.85)] - pub async fn and_run2( - self, - mut callback: impl AsyncFnMut(&mut ClientSession) -> Result, - ) -> Result { + pub async fn and_run2(self, mut callback: F) -> Result + where + F: for<'b> AsyncFnMut(&'b mut ClientSession) -> Result, + { convenient_run!( self.session, self.session From 5bf9999ea9b52e51a188cf0f5e2bec5c1b74f037 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 8 May 2025 14:22:10 -0400 Subject: [PATCH 6/7] revert unneeded change --- src/test/spec/unified_runner/operation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/spec/unified_runner/operation.rs b/src/test/spec/unified_runner/operation.rs index a823f88fd..82e2bcd45 100644 --- a/src/test/spec/unified_runner/operation.rs +++ b/src/test/spec/unified_runner/operation.rs @@ -157,7 +157,7 @@ pub(crate) trait TestOperation: Debug + Send + Sync { /// so that we can continue to borrow the entity map in other ways even when we're using a session, /// which we'd have to borrow mutably from the map. macro_rules! with_mut_session { - ($test_runner:expr, $id:expr, |$session:ident| $body:expr) => { + ($test_runner:ident, $id:expr, |$session:ident| $body:expr) => { async { let id = $id; let entity = $test_runner.entities.write().await.remove(id).unwrap(); From 97ad899c40404fe591ff963473c7f47b31690a01 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 8 May 2025 14:31:56 -0400 Subject: [PATCH 7/7] bump clippy --- .evergreen/check-clippy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.evergreen/check-clippy.sh b/.evergreen/check-clippy.sh index 29e6324d1..c3c0761c0 100755 --- a/.evergreen/check-clippy.sh +++ b/.evergreen/check-clippy.sh @@ -5,7 +5,7 @@ set -o errexit source ./.evergreen/env.sh # Pin clippy to the latest version. This should be updated when new versions of Rust are released. -CLIPPY_VERSION=1.84.0 +CLIPPY_VERSION=1.85.0 rustup install $CLIPPY_VERSION