This is an automated email from the ASF dual-hosted git repository.
hubcio pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git
The following commit(s) were added to refs/heads/master by this push:
new 2c1f70b53 chore(repo): bump Rust toolchain to 1.99.0 (#4430)
2c1f70b53 is described below
commit 2c1f70b53e5a116cb55e8a5b6463cd85c2b0497c
Author: Hubert Gruszecki <[email protected]>
AuthorDate: Wed Oct 7 11:50:06 2026 +0200
chore(repo): bump Rust toolchain to 1.99.0 (#4430)
---
.devcontainer/Dockerfile | 2 +-
Cargo.lock | 1 -
Cargo.toml | 1 -
Dockerfile | 2 +-
bdd/php/Dockerfile | 2 +-
bdd/python/Dockerfile | 2 +-
bdd/rust/Dockerfile | 2 +-
core/ai/mcp/Dockerfile | 2 +-
core/bench/dashboard/frontend/src/api/mod.rs | 9 ++++---
.../frontend/src/components/app_content.rs | 28 ++++++++++++++--------
.../frontend/src/components/chart/trend_chart.rs | 4 +++-
.../frontend/src/components/layout/sidebar.rs | 4 +++-
.../dashboard/frontend/src/state/benchmark.rs | 22 ++++++++++-------
core/bench/dashboard/server/Dockerfile | 2 +-
core/bench/report/Cargo.toml | 1 -
core/bench/report/src/types/hardware.rs | 2 +-
core/bench/src/utils/client_factory.rs | 20 +++++++---------
core/binary_protocol/src/framing.rs | 6 ++---
core/connectors/runtime/Dockerfile | 2 +-
core/consensus/src/client_table.rs | 2 +-
core/consensus/src/impls.rs | 2 +-
.../tests/connectors/runtime/http_state.rs | 2 +-
core/journal/src/prepare_journal.rs | 2 +-
core/metadata/src/impls/metadata.rs | 18 +++++++-------
core/metadata/src/stm/mux.rs | 2 +-
core/metadata/src/stm/stream.rs | 2 +-
core/metadata/src/stm/user.rs | 23 ++++++++----------
core/partitions/src/iggy_partition.rs | 23 +++++++-----------
core/partitions/src/offset_recovery.rs | 4 ++--
core/partitions/src/persistence.rs | 2 +-
core/server/Dockerfile | 2 +-
core/server/src/consumer_group.rs | 6 ++---
core/server/src/consumer_group/lease.rs | 4 ++--
core/server/src/consumer_group/liveness.rs | 6 ++---
core/server/src/http/session.rs | 4 ++--
core/server/src/http/wire.rs | 2 +-
core/server/src/partition_helpers.rs | 6 ++---
core/server/src/sysinfo_probe.rs | 2 +-
core/server_common/src/iobuf.rs | 2 +-
core/shard/src/lib.rs | 2 +-
core/shard/src/poll/completion.rs | 2 +-
core/simulator/src/executor/time.rs | 4 ++--
core/simulator/src/lib.rs | 4 ++--
foreign/cpp/MODULE.bazel | 2 +-
foreign/php/Dockerfile.test | 2 +-
gateways/kafka/Dockerfile | 2 +-
gateways/kafka/src/protocol/acl.rs | 4 ++--
gateways/kafka/src/protocol/handlers/metadata.rs | 2 +-
.../kafka/tests/bridge_iggy_integration_tests.rs | 2 +-
gateways/kafka/tests/consumer_group_tests.rs | 10 ++++----
gateways/kafka/tests/fetch_real_bridge_tests.rs | 8 +++----
gateways/kafka/tests/metadata_real_bridge_tests.rs | 2 +-
gateways/kafka/tests/produce_real_bridge_tests.rs | 2 +-
gateways/kafka/tests/server_e2e_tests.rs | 2 +-
rust-toolchain.toml | 2 +-
55 files changed, 141 insertions(+), 141 deletions(-)
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 7670fb4d3..61d6fc1dd 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -17,7 +17,7 @@
# Toolchain is pinned by rust-toolchain.toml. The base
# image ships rustup, so the pin auto-resolves on first cargo invocation.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
FROM rust:${RUST_VERSION}-slim-trixie
# Build + runtime dependencies mirror the production Dockerfile builder
diff --git a/Cargo.lock b/Cargo.lock
index 961adcb98..2607dd79b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1998,7 +1998,6 @@ dependencies = [
"charming",
"colored",
"comfy-table",
- "derive-new",
"derive_more",
"human-repr",
"rand 0.10.2",
diff --git a/Cargo.toml b/Cargo.toml
index 82267292f..21cee6bc0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -161,7 +161,6 @@ cyper-core = { version = "0.9.0", default-features = false }
darling = "0.24"
dashmap = "6.2.1"
deltalake = { version = "0.32.4", features = ["azure", "gcs", "s3"] }
-derive-new = "0.7.0"
derive_builder = "0.20.2"
derive_more = { version = "2.1.1", features = ["full"] }
dircpy = "0.3.20"
diff --git a/Dockerfile b/Dockerfile
index bd0c75544..3af000f59 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
FROM rust:${RUST_VERSION}-slim-trixie AS builder
WORKDIR /build
diff --git a/bdd/php/Dockerfile b/bdd/php/Dockerfile
index b5d7adb74..8d2fd8fd4 100644
--- a/bdd/php/Dockerfile
+++ b/bdd/php/Dockerfile
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
FROM rust:${RUST_VERSION}-slim-trixie AS rust-toolchain
FROM ubuntu:24.04
diff --git a/bdd/python/Dockerfile b/bdd/python/Dockerfile
index 323fbf070..113650179 100644
--- a/bdd/python/Dockerfile
+++ b/bdd/python/Dockerfile
@@ -16,7 +16,7 @@
# under the License.
# syntax=docker/dockerfile:1
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
FROM rust:${RUST_VERSION}-slim-trixie
RUN apt-get update && \
diff --git a/bdd/rust/Dockerfile b/bdd/rust/Dockerfile
index 1d9888da3..ff967433d 100644
--- a/bdd/rust/Dockerfile
+++ b/bdd/rust/Dockerfile
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
FROM rust:${RUST_VERSION}-slim-trixie
WORKDIR /app
diff --git a/core/ai/mcp/Dockerfile b/core/ai/mcp/Dockerfile
index 7d22fc122..e7d6c6df0 100644
--- a/core/ai/mcp/Dockerfile
+++ b/core/ai/mcp/Dockerfile
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
ARG ALPINE_VERSION=3.23
FROM --platform=$BUILDPLATFORM
lukemathwalker/cargo-chef:latest-rust-${RUST_VERSION}-alpine${ALPINE_VERSION}
AS chef
diff --git a/core/bench/dashboard/frontend/src/api/mod.rs
b/core/bench/dashboard/frontend/src/api/mod.rs
index d6edcc4f0..449357276 100644
--- a/core/bench/dashboard/frontend/src/api/mod.rs
+++ b/core/bench/dashboard/frontend/src/api/mod.rs
@@ -218,11 +218,10 @@ pub async fn fetch_benchmark_trend(
pub fn download_test_artifacts(uuid: &Uuid) {
let url = format!("{}/api/artifacts/{}", get_api_base_url(), uuid);
- if let Some(window) = window() {
- let _ = window
- .location()
- .set_href(&url)
- .map_err(|_| log!("Failed to initiate download"));
+ if let Some(window) = window()
+ && window.location().set_href(&url).is_err()
+ {
+ log!("Failed to initiate download");
}
}
diff --git a/core/bench/dashboard/frontend/src/components/app_content.rs
b/core/bench/dashboard/frontend/src/components/app_content.rs
index beb65d7b5..f4b51da05 100644
--- a/core/bench/dashboard/frontend/src/components/app_content.rs
+++ b/core/bench/dashboard/frontend/src/components/app_content.rs
@@ -72,10 +72,12 @@ async fn apply_benchmark(
target_benchmark,
))));
}
- Err(error) => log!(format!(
- "AppContent: fetch benchmark {} failed: {}",
- uuid, error
- )),
+ Err(error) => {
+ log!(format!(
+ "AppContent: fetch benchmark {} failed: {}",
+ uuid, error
+ ));
+ }
}
}
@@ -185,10 +187,12 @@ pub fn app_content() -> Html {
))));
}
}
- Err(error) => log!(format!(
- "AppContent: fetch right benchmark {} failed:
{}",
- right_uuid, error
- )),
+ Err(error) => {
+ log!(format!(
+ "AppContent: fetch right benchmark {}
failed: {}",
+ right_uuid, error
+ ));
+ }
}
if is_current() {
is_loading_handle.set(false);
@@ -308,7 +312,9 @@ fn use_init_hardware(
}
}
}
- Err(error) => log!(format!("Error fetching hardware: {}",
error)),
+ Err(error) => {
+ log!(format!("Error fetching hardware: {}", error));
+ }
}
});
|| ()
@@ -371,7 +377,9 @@ fn use_load_gitrefs(
.emit(GitrefAction::SetSelectedGitref(Some(final_gitref)));
}
}
- Err(error) => log!(format!("Error fetching gitrefs:
{}", error)),
+ Err(error) => {
+ log!(format!("Error fetching gitrefs: {}", error));
+ }
}
});
}
diff --git a/core/bench/dashboard/frontend/src/components/chart/trend_chart.rs
b/core/bench/dashboard/frontend/src/components/chart/trend_chart.rs
index 1e8b96ae3..2a30c7a36 100644
--- a/core/bench/dashboard/frontend/src/components/chart/trend_chart.rs
+++ b/core/bench/dashboard/frontend/src/components/chart/trend_chart.rs
@@ -102,7 +102,9 @@ pub fn trend_chart(props: &TrendChartProps) -> Html {
// Render new chart
match create_chart(&config, data, &plot_type) {
Ok(new_e) => echarts.set(Some(new_e)),
- Err(e) => log!(format!("Error rendering chart: {}",
e)),
+ Err(e) => {
+ log!(format!("Error rendering chart: {}", e));
+ }
}
} else {
log!("No data to render chart");
diff --git a/core/bench/dashboard/frontend/src/components/layout/sidebar.rs
b/core/bench/dashboard/frontend/src/components/layout/sidebar.rs
index 32898b0b7..099395972 100644
--- a/core/bench/dashboard/frontend/src/components/layout/sidebar.rs
+++ b/core/bench/dashboard/frontend/src/components/layout/sidebar.rs
@@ -78,7 +78,9 @@ pub fn sidebar(_props: &SidebarProps) -> Html {
}
benchmarks_handle.set(data);
}
- Err(error) => log!(format!("Sidebar:
fetch_recent_benchmarks failed: {error}")),
+ Err(error) => {
+ log!(format!("Sidebar: fetch_recent_benchmarks failed:
{error}"));
+ }
}
if !cancelled_async.get() {
is_loading_handle.set(false);
diff --git a/core/bench/dashboard/frontend/src/state/benchmark.rs
b/core/bench/dashboard/frontend/src/state/benchmark.rs
index 4838b4979..14b522d87 100644
--- a/core/bench/dashboard/frontend/src/state/benchmark.rs
+++ b/core/bench/dashboard/frontend/src/state/benchmark.rs
@@ -48,15 +48,19 @@ impl BenchmarkState {
selected_benchmark: &Option<BenchmarkReportLight>,
) {
match selected_benchmark {
- Some(bm) => log!(format!(
- "Selected benchmark: kind={}, params={:?}",
- format!("{:?}", selected_kind), // Explicitly format kind
- bm.params
- )),
- None => log!(format!(
- "No benchmark selected, kind is {}",
- format!("{:?}", selected_kind)
- )),
+ Some(bm) => {
+ log!(format!(
+ "Selected benchmark: kind={}, params={:?}",
+ format!("{:?}", selected_kind), // Explicitly format kind
+ bm.params
+ ));
+ }
+ None => {
+ log!(format!(
+ "No benchmark selected, kind is {}",
+ format!("{:?}", selected_kind)
+ ));
+ }
}
}
}
diff --git a/core/bench/dashboard/server/Dockerfile
b/core/bench/dashboard/server/Dockerfile
index be06758eb..c170859bc 100644
--- a/core/bench/dashboard/server/Dockerfile
+++ b/core/bench/dashboard/server/Dockerfile
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
# Build stage
FROM rust:${RUST_VERSION}-slim-trixie AS builder
diff --git a/core/bench/report/Cargo.toml b/core/bench/report/Cargo.toml
index db83cc8a0..2a03624de 100644
--- a/core/bench/report/Cargo.toml
+++ b/core/bench/report/Cargo.toml
@@ -27,7 +27,6 @@ publish = false
charming = { workspace = true }
colored = { workspace = true }
comfy-table = { workspace = true }
-derive-new = { workspace = true }
derive_more = { workspace = true }
human-repr = { workspace = true }
rand = { workspace = true }
diff --git a/core/bench/report/src/types/hardware.rs
b/core/bench/report/src/types/hardware.rs
index 921b60f96..f22580153 100644
--- a/core/bench/report/src/types/hardware.rs
+++ b/core/bench/report/src/types/hardware.rs
@@ -18,7 +18,7 @@
use serde::{Deserialize, Serialize};
use sysinfo::System;
-#[derive(Debug, Serialize, Deserialize, Clone, derive_new::new, PartialEq,
Default)]
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
pub struct BenchmarkHardware {
pub identifier: Option<String>,
pub cpu_name: String,
diff --git a/core/bench/src/utils/client_factory.rs
b/core/bench/src/utils/client_factory.rs
index 82d7f57d7..7ed851b7f 100644
--- a/core/bench/src/utils/client_factory.rs
+++ b/core/bench/src/utils/client_factory.rs
@@ -114,20 +114,18 @@ impl ClientFactory for TcpClientFactory {
)
});
Client::connect(&client).await.unwrap_or_else(|e| {
- if self.tls_enabled {
- panic!(
- "Failed to connect to iggy-server at {} with TLS enabled,
error: {:?}\n\
+ assert!(
+ !self.tls_enabled,
+ "Failed to connect to iggy-server at {} with TLS enabled,
error: {:?}\n\
Hint: Make sure the server is started with TLS enabled and
self-signed certificate:\n\
IGGY_TCP_TLS_ENABLED=true IGGY_TCP_TLS_SELF_SIGNED=true\n
or start iggy-bench with relevant tcp tls arguments: --tls
--tls-domain <domain> --tls-ca-file <ca_file>\n",
- self.server_addr, e
- )
- } else {
- panic!(
- "Failed to connect to iggy-server at {}, error: {:?}",
- self.server_addr, e
- )
- }
+ self.server_addr, e
+ );
+ panic!(
+ "Failed to connect to iggy-server at {}, error: {:?}",
+ self.server_addr, e
+ )
});
ClientWrapper::Tcp(client)
}
diff --git a/core/binary_protocol/src/framing.rs
b/core/binary_protocol/src/framing.rs
index dc1f5ed0c..a45b2840b 100644
--- a/core/binary_protocol/src/framing.rs
+++ b/core/binary_protocol/src/framing.rs
@@ -244,7 +244,7 @@ mod tests {
assert_eq!(consumed, 16);
assert_eq!(frame.code, 1);
assert_eq!(frame.request_id, 99);
- assert!(frame.payload.is_empty());
+ assert_eq!(frame.payload, []);
}
#[test]
@@ -334,7 +334,7 @@ mod tests {
assert_eq!(consumed, 16);
assert!(frame.is_ok());
assert_eq!(frame.request_id, 42);
- assert!(frame.payload.is_empty());
+ assert_eq!(frame.payload, []);
}
#[test]
@@ -347,7 +347,7 @@ mod tests {
assert!(!frame.is_ok());
assert_eq!(frame.status, 1001);
assert_eq!(frame.request_id, 55);
- assert!(frame.payload.is_empty());
+ assert_eq!(frame.payload, []);
}
#[test]
diff --git a/core/connectors/runtime/Dockerfile
b/core/connectors/runtime/Dockerfile
index cbfcc7c51..590e9ae1d 100644
--- a/core/connectors/runtime/Dockerfile
+++ b/core/connectors/runtime/Dockerfile
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
ARG ALPINE_VERSION=3.23
FROM --platform=$BUILDPLATFORM
lukemathwalker/cargo-chef:latest-rust-${RUST_VERSION}-alpine${ALPINE_VERSION}
AS chef
diff --git a/core/consensus/src/client_table.rs
b/core/consensus/src/client_table.rs
index ba5f94a5b..c23f3cffe 100644
--- a/core/consensus/src/client_table.rs
+++ b/core/consensus/src/client_table.rs
@@ -2748,7 +2748,7 @@ mod tests {
)
.is_err()
);
- assert!(clients_of(&table).is_empty());
+ assert_eq!(clients_of(&table), [] as [u128; 0]);
}
#[cfg(debug_assertions)]
diff --git a/core/consensus/src/impls.rs b/core/consensus/src/impls.rs
index cd17643cc..a88b31296 100644
--- a/core/consensus/src/impls.rs
+++ b/core/consensus/src/impls.rs
@@ -5581,7 +5581,7 @@ mod vsr_consensus_tests {
panic!("the settled primary must answer the backup's probe:
{replies:?}");
};
assert_eq!(*target, Some(REJOINING_REPLICA));
- assert!(suffix.is_empty());
+ assert_eq!(suffix.as_slice(), []);
let response =
Message::<StartViewHeader>::new(size_of::<StartViewHeader>())
.transmute_header(|_, header: &mut StartViewHeader| {
header.command = Command::StartView;
diff --git a/core/integration/tests/connectors/runtime/http_state.rs
b/core/integration/tests/connectors/runtime/http_state.rs
index ed038362f..fe461b96b 100644
--- a/core/integration/tests/connectors/runtime/http_state.rs
+++ b/core/integration/tests/connectors/runtime/http_state.rs
@@ -123,7 +123,7 @@ impl Respond for StateStoreResponder {
}
if store
.fail_next_puts
- .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |remaining| {
+ .try_update(Ordering::SeqCst, Ordering::SeqCst, |remaining| {
remaining.checked_sub(1)
})
.is_ok()
diff --git a/core/journal/src/prepare_journal.rs
b/core/journal/src/prepare_journal.rs
index be4013740..b44e78f5a 100644
--- a/core/journal/src/prepare_journal.rs
+++ b/core/journal/src/prepare_journal.rs
@@ -1981,7 +1981,7 @@ mod tests {
assert_eq!(from_4[0].op, 5);
let from_10 = journal.iter_headers_from(10);
- assert!(from_10.is_empty());
+ assert_eq!(from_10, []);
}
#[compio::test]
diff --git a/core/metadata/src/impls/metadata.rs
b/core/metadata/src/impls/metadata.rs
index f334a74d7..0906e341c 100644
--- a/core/metadata/src/impls/metadata.rs
+++ b/core/metadata/src/impls/metadata.rs
@@ -6486,12 +6486,12 @@ mod tests {
.unwrap(),
Some(session + 1)
);
- assert!(
+ assert_eq!(
metadata
.mux_stm
.streams()
- .consumer_group_memberships(CLIENT)
- .is_empty()
+ .consumer_group_memberships(CLIENT),
+ []
);
assert_eq!(metadata.client_table.borrow().get_epoch(CLIENT), None);
assert_eq!(metadata.mux_stm.streams().consumer_group_count(), 1);
@@ -6517,12 +6517,12 @@ mod tests {
None
);
- assert!(
+ assert_eq!(
metadata
.mux_stm
.streams()
- .consumer_group_memberships(CLIENT)
- .is_empty()
+ .consumer_group_memberships(CLIENT),
+ []
);
assert_eq!(metadata.mux_stm.streams().consumer_group_count(), 1);
assert_eq!(metadata.consensus.as_ref().unwrap().commit_min(), 2);
@@ -6681,12 +6681,12 @@ mod tests {
.unwrap()
.is_some()
);
- assert!(
+ assert_eq!(
metadata
.mux_stm
.streams()
- .consumer_group_memberships(CLIENT)
- .is_empty()
+ .consumer_group_memberships(CLIENT),
+ []
);
assert_eq!(metadata.client_table.borrow().count(), capacity);
}
diff --git a/core/metadata/src/stm/mux.rs b/core/metadata/src/stm/mux.rs
index f9e163fb2..6c611b903 100644
--- a/core/metadata/src/stm/mux.rs
+++ b/core/metadata/src/stm/mux.rs
@@ -318,7 +318,7 @@ mod tests {
// Encode to bytes
let encoded = snapshot.encode().unwrap();
- assert!(!encoded.is_empty());
+ assert_ne!(encoded, b"");
// Decode from bytes
let decoded = IggySnapshot::decode(&encoded).unwrap();
diff --git a/core/metadata/src/stm/stream.rs b/core/metadata/src/stm/stream.rs
index 330c2a0bd..6ac1e50e1 100644
--- a/core/metadata/src/stm/stream.rs
+++ b/core/metadata/src/stm/stream.rs
@@ -1729,7 +1729,7 @@ impl Streams {
}
let current = topic
.round_robin_counter
- .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |c| {
+ .try_update(Ordering::Relaxed, Ordering::Relaxed, |c| {
Some((c + 1) % count)
})
.unwrap_or(0);
diff --git a/core/metadata/src/stm/user.rs b/core/metadata/src/stm/user.rs
index 64a7652bc..0280dee2c 100644
--- a/core/metadata/src/stm/user.rs
+++ b/core/metadata/src/stm/user.rs
@@ -1544,21 +1544,18 @@ mod tests {
// The derived index is not serialized: every permissioner vec is
empty.
let snap = &snapshot.permissioner;
- assert!(snap.users_permissions.is_empty());
- assert!(snap.users_streams_permissions.is_empty());
- assert!(
- snap.users_that_can_poll_messages_from_all_streams
- .is_empty()
- );
- assert!(snap.users_that_can_send_messages_to_all_streams.is_empty());
- assert!(
- snap.users_that_can_poll_messages_from_specific_streams
- .is_empty()
+ assert_eq!(snap.users_permissions, []);
+ assert_eq!(snap.users_streams_permissions, []);
+ assert_eq!(
+ snap.users_that_can_poll_messages_from_all_streams,
+ [] as [u32; 0]
);
- assert!(
- snap.users_that_can_send_messages_to_specific_streams
- .is_empty()
+ assert_eq!(
+ snap.users_that_can_send_messages_to_all_streams,
+ [] as [u32; 0]
);
+ assert_eq!(snap.users_that_can_poll_messages_from_specific_streams,
[]);
+ assert_eq!(snap.users_that_can_send_messages_to_specific_streams, []);
let restored = Users::from_snapshot(snapshot).expect("snapshot
restore");
let (poll_ok, send_ok, in_poll_all, in_send_specific) =
restored.read(|inner| {
diff --git a/core/partitions/src/iggy_partition.rs
b/core/partitions/src/iggy_partition.rs
index 9260bb383..b30e7b31f 100644
--- a/core/partitions/src/iggy_partition.rs
+++ b/core/partitions/src/iggy_partition.rs
@@ -3056,7 +3056,6 @@ where
if keyed_by_group(pending.kind) && tracked.is_none() {
self.mark_consumer_group_offsets_need_reconcile();
}
- Ok(())
}
PendingConsumerOffsetMutation::Upsert(offset) => {
if let Some(path) = path.as_deref() {
@@ -3075,7 +3074,6 @@ where
if keyed_by_group(pending.kind) && created {
self.mark_consumer_group_offsets_need_reconcile();
}
- Ok(())
}
PendingConsumerOffsetMutation::Delete => {
if let Some(path) = path.as_deref() {
@@ -3113,9 +3111,9 @@ where
.remove(pending.kind, pending.consumer_id);
capacity.forget_inactive_provisional(pending.consumer_id);
capacity.rearm_if_below_limit(&self.durable_consumer_offsets);
- Ok(())
}
}
+ Ok(())
}
/// Accept a read only while its message history still belongs to this
owner.
@@ -11579,7 +11577,7 @@ mod tests {
assert_eq!(cursor.u64().unwrap(), CHECKPOINT_OP);
let wire =
crate::state_transfer::ConsumerOffsetsWire::decode(cursor.remaining()).unwrap();
assert!(wire.consumers.is_empty() && wire.groups.is_empty());
- assert!(wire.checkpoint_prepare.is_empty());
+ assert_eq!(wire.checkpoint_prepare, b"");
assert_eq!(wire.required_metadata_frontier, METADATA_FRONTIER);
let mut recovered = test_partition();
recovered.set_partition_dir(directory.path().to_string_lossy().into_owned());
@@ -13905,7 +13903,7 @@ mod tests {
(ConsumerKind::ConsumerGroup, 9)
]
);
- assert!(partition.dead_group_offset_keys(|_| true).is_empty());
+ assert_eq!(partition.dead_group_offset_keys(|_| true), []);
}
/// The reconciler deletes a bounded number of dead keys per pass. Ordered
@@ -14586,7 +14584,7 @@ mod tests {
.unwrap();
assert!(epoch.get() > initial);
let after_create = epoch.get();
- assert!(partition.dead_group_offset_keys(|_| true).is_empty());
+ assert_eq!(partition.dead_group_offset_keys(|_| true), []);
assert_eq!(epoch.get(), after_create);
partition.stage_consumer_offset_upsert(2, ConsumerKind::ConsumerGroup,
7, 2, true);
partition
@@ -16165,7 +16163,7 @@ mod tests {
partition.occupied_consumer_offset_count(ConsumerKind::ConsumerGroup),
0
);
- assert!(partition.consumer_group_offset_ids().is_empty());
+ assert_eq!(partition.consumer_group_offset_ids(), [] as [u64; 0]);
}
#[compio::test]
@@ -16207,12 +16205,7 @@ mod tests {
vec![(ConsumerKind::ConsumerGroup, 7)],
"the same dead key is reclaimed once it is no longer stranded"
);
- assert!(
- partition
- .offsets_wire_snapshot_for_test()
- .unwrap()
- .is_empty()
- );
+ assert_eq!(partition.offsets_wire_snapshot_for_test().unwrap(), []);
}
#[test]
@@ -16506,7 +16499,7 @@ mod tests {
ConsumerOffset::new(ConsumerKind::ConsumerGroup, 7, 11,
String::new()),
);
partition.seed_recovered_consumer_offset(ConsumerKind::ConsumerGroup,
7, 11, 11);
- assert!(partition.dead_group_offset_keys(|_| false).is_empty());
+ assert_eq!(partition.dead_group_offset_keys(|_| false), []);
assert_eq!(
partition.durable_consumer_offset_count(ConsumerKind::ConsumerGroup),
1
@@ -18473,7 +18466,7 @@ mod tests {
assert_eq!(&body[..], &[0, 0, 0, 0]);
let (response, _) = SendMessagesResponse::decode(&body).unwrap();
- assert!(response.confirmations.is_empty());
+ assert_eq!(response.confirmations, []);
}
#[test]
diff --git a/core/partitions/src/offset_recovery.rs
b/core/partitions/src/offset_recovery.rs
index 650054d49..b0fa454df 100644
--- a/core/partitions/src/offset_recovery.rs
+++ b/core/partitions/src/offset_recovery.rs
@@ -405,12 +405,12 @@ mod tests {
assert!(dir.path().join("notes.tmp").exists());
assert_eq!(consumers.entries.len(), 1);
assert_eq!(consumers.entries[0].consumer_id, 9);
- assert!(consumers.stranded_ids.is_empty());
+ assert_eq!(consumers.stranded_ids, [] as [u32; 0]);
assert!(!dir.path().join("8").exists());
assert!(!dir.path().join("10").exists());
let groups = load_consumer_group_offsets(path).await.unwrap();
assert_eq!(groups.entries.len(), 1);
assert_eq!(groups.entries[0].0, ConsumerGroupId(9));
- assert!(groups.stranded_ids.is_empty());
+ assert_eq!(groups.stranded_ids, [] as [u32; 0]);
}
}
diff --git a/core/partitions/src/persistence.rs
b/core/partitions/src/persistence.rs
index 385187a8f..b10539f0a 100644
--- a/core/partitions/src/persistence.rs
+++ b/core/partitions/src/persistence.rs
@@ -89,7 +89,7 @@ struct OffsetFilePermit;
impl OffsetFilePermit {
fn acquire() -> Option<Self> {
RETAINED_OFFSET_FILES
- .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |count| {
+ .try_update(Ordering::Relaxed, Ordering::Relaxed, |count| {
(count < *OFFSET_FILE_LIMIT).then_some(count + 1)
})
.ok()
diff --git a/core/server/Dockerfile b/core/server/Dockerfile
index 913dd6582..88368d4d2 100644
--- a/core/server/Dockerfile
+++ b/core/server/Dockerfile
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
ARG ALPINE_VERSION=3.23
# ── from-source path ─────────────────────────────────────────────────────────
diff --git a/core/server/src/consumer_group.rs
b/core/server/src/consumer_group.rs
index f7b45b3a1..410bb59fc 100644
--- a/core/server/src/consumer_group.rs
+++ b/core/server/src/consumer_group.rs
@@ -382,11 +382,11 @@ mod tests {
)
.await
.unwrap();
- assert!(
+ assert_eq!(
ReplicatedJoinConsumerGroupRequest::decode_from(request_body(&accepted))
.unwrap()
- .in_flight
- .is_empty()
+ .in_flight,
+ [] as [u32; 0]
);
apply_join(&shard, &accepted);
assert_eq!(
diff --git a/core/server/src/consumer_group/lease.rs
b/core/server/src/consumer_group/lease.rs
index ccce26e0b..113b38544 100644
--- a/core/server/src/consumer_group/lease.rs
+++ b/core/server/src/consumer_group/lease.rs
@@ -340,14 +340,14 @@ mod tests {
tracker.observe_local_session(&activity);
let now = Instant::now();
assert_eq!(tracker.local_activity(now, TIMEOUT), vec![identity]);
- assert!(tracker.local_activity(now + TIMEOUT, TIMEOUT).is_empty());
+ assert_eq!(tracker.local_activity(now + TIMEOUT, TIMEOUT), []);
activity.touch();
assert_eq!(
tracker.local_activity(Instant::now(), TIMEOUT),
vec![identity]
);
drop(activity);
- assert!(tracker.local_activity(now, TIMEOUT).is_empty());
+ assert_eq!(tracker.local_activity(now, TIMEOUT), []);
assert!(tracker.local_sessions.is_empty());
}
}
diff --git a/core/server/src/consumer_group/liveness.rs
b/core/server/src/consumer_group/liveness.rs
index 61ba00395..6d994d0d9 100644
--- a/core/server/src/consumer_group/liveness.rs
+++ b/core/server/src/consumer_group/liveness.rs
@@ -952,12 +952,12 @@ mod tests {
expire_sessions(&shard, &tracker, &receiver, &shutdown, TIMEOUT,
expired_at).await,
Pass::Drained
);
- assert!(
+ assert_eq!(
metadata
.mux_stm
.streams()
- .consumer_group_memberships(CLIENT)
- .is_empty()
+ .consumer_group_memberships(CLIENT),
+ []
);
}
diff --git a/core/server/src/http/session.rs b/core/server/src/http/session.rs
index ff1dd8d85..0d2cf368d 100644
--- a/core/server/src/http/session.rs
+++ b/core/server/src/http/session.rs
@@ -476,7 +476,7 @@ mod tests {
table.insert(session.key.clone(), session);
}
let torn = sweep_expired(&mut table, 100);
- assert!(torn.is_empty());
+ assert_eq!(torn, []);
assert_eq!(table.len(), 8, "no live session is evicted to make room");
assert_eq!(registries.len(), table.len());
}
@@ -505,7 +505,7 @@ mod tests {
assert!(live_entry(&table, &session.key, 100).is_some());
assert!(registry.end_session(session.client_id, session.user_id,
session.session, 2));
assert!(live_entry(&table, &session.key, 100).is_none());
- assert!(sweep_expired(&mut table, 100).is_empty());
+ assert_eq!(sweep_expired(&mut table, 100), []);
assert!(table.is_empty());
}
diff --git a/core/server/src/http/wire.rs b/core/server/src/http/wire.rs
index 048361c85..ada139818 100644
--- a/core/server/src/http/wire.rs
+++ b/core/server/src/http/wire.rs
@@ -591,6 +591,6 @@ mod tests {
let polled = resync_required_polled_messages();
assert_eq!(polled.partition_id, RESYNC_REQUIRED_PARTITION_SENTINEL);
assert_eq!(polled.count, 0);
- assert!(polled.messages.is_empty());
+ assert_eq!(polled.messages, []);
}
}
diff --git a/core/server/src/partition_helpers.rs
b/core/server/src/partition_helpers.rs
index 4f5ba3fef..02d727f6d 100644
--- a/core/server/src/partition_helpers.rs
+++ b/core/server/src/partition_helpers.rs
@@ -649,7 +649,7 @@ async fn load_partition(
&& !first_initialization
&&
!journal::PartitionPrepareJournal::has_published_frontier(&directory)
.await
- .map_err(&wal_error)?
+ .map_err(wal_error)?
{
return Err(wal_error(std::io::Error::new(
std::io::ErrorKind::InvalidData,
@@ -662,7 +662,7 @@ async fn load_partition(
partition_metadata.created_revision,
)
.await
- .map_err(&wal_error)?;
+ .map_err(wal_error)?;
}
let (persistence, prepares) = PartitionPersistence::open_with_capacity(
&directory,
@@ -675,7 +675,7 @@ async fn load_partition(
.unwrap_or(iggy_common::DEFAULT_PREALLOCATE_SEGMENTS),
)
.await
- .map_err(&wal_error)?;
+ .map_err(wal_error)?;
if let Some(log_view) = persistence.certified_log_view()
&& log_view != 0
&& log_view < partition_metadata.created_view
diff --git a/core/server/src/sysinfo_probe.rs b/core/server/src/sysinfo_probe.rs
index 8f8576f8c..22d8398c3 100644
--- a/core/server/src/sysinfo_probe.rs
+++ b/core/server/src/sysinfo_probe.rs
@@ -214,7 +214,7 @@ mod tests {
// here means the probe wired nothing (the pre-fix stubbed literal).
assert_eq!(stats.process_id, std::process::id());
assert!(stats.total_memory > 0);
- assert!(!stats.hostname.is_empty());
+ assert_ne!(stats.hostname, "");
}
#[test]
diff --git a/core/server_common/src/iobuf.rs b/core/server_common/src/iobuf.rs
index 8f97b86a6..fb4f07bd1 100644
--- a/core/server_common/src/iobuf.rs
+++ b/core/server_common/src/iobuf.rs
@@ -386,7 +386,7 @@ impl ControlBlock {
len,
capacity,
});
- unsafe { NonNull::new_unchecked(Box::into_raw(ctrl)) }
+ Box::into_non_null(ctrl)
}
}
diff --git a/core/shard/src/lib.rs b/core/shard/src/lib.rs
index eff6cf5da..82ddc5067 100644
--- a/core/shard/src/lib.rs
+++ b/core/shard/src/lib.rs
@@ -12703,7 +12703,7 @@ mod control_frame_tests {
let msg = frame(0, 0);
let body = control_suffix_body_verified(&msg,
msg.header().checksum_body)
.expect("a header-only frame has nothing to verify");
- assert!(body.is_empty());
+ assert_eq!(body, b"");
}
}
diff --git a/core/shard/src/poll/completion.rs
b/core/shard/src/poll/completion.rs
index 9aa83e7f9..4df51897c 100644
--- a/core/shard/src/poll/completion.rs
+++ b/core/shard/src/poll/completion.rs
@@ -86,7 +86,7 @@ impl PollCompletionLane {
if self
.state
.reserved
- .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |reserved| {
+ .try_update(Ordering::Relaxed, Ordering::Relaxed, |reserved| {
(reserved < self.state.capacity).then_some(reserved + 1)
})
.is_err()
diff --git a/core/simulator/src/executor/time.rs
b/core/simulator/src/executor/time.rs
index ab763562e..56e07de95 100644
--- a/core/simulator/src/executor/time.rs
+++ b/core/simulator/src/executor/time.rs
@@ -254,7 +254,7 @@ mod tests {
// Partial advance: nothing is due yet, and the first poll landing
// after time already moved must not re-anchor the deadline to poll
// time (a poll-anchored deadline would sit at 16ms).
- assert!(handle.advance(Duration::from_millis(6)).is_empty());
+ assert_eq!(handle.advance(Duration::from_millis(6)), [] as [u64; 0]);
assert_eq!(poll_once(&mut sleep), Poll::Pending);
// Crossing the creation-anchored 10ms deadline fires exactly once.
@@ -277,6 +277,6 @@ mod tests {
let handle = TimerHandle::new();
let sleep = handle.sleep(Duration::from_millis(5));
drop(sleep);
- assert!(handle.advance(Duration::from_millis(10)).is_empty());
+ assert_eq!(handle.advance(Duration::from_millis(10)), [] as [u64; 0]);
}
}
diff --git a/core/simulator/src/lib.rs b/core/simulator/src/lib.rs
index c176dd5d2..191e68d49 100644
--- a/core/simulator/src/lib.rs
+++ b/core/simulator/src/lib.rs
@@ -6663,7 +6663,7 @@ mod partition_repair_driver_tests {
.is_none(),
"resident operations must not consume a repair session while
waiting for the next walk"
);
- assert!(repair_requests(&sim).is_empty());
+ assert_eq!(repair_requests(&sim), []);
let mut namespace_scratch = Vec::new();
assert!(
@@ -6674,7 +6674,7 @@ mod partition_repair_driver_tests {
(Status::Normal, 0, OPS as u64, OPS as u64),
"the existing tick must finish the resident backlog without peer
repair"
);
- assert!(repair_requests(&sim).is_empty());
+ assert_eq!(repair_requests(&sim), []);
}
#[test]
diff --git a/foreign/cpp/MODULE.bazel b/foreign/cpp/MODULE.bazel
index 5b05e43f4..54d5b6c4d 100644
--- a/foreign/cpp/MODULE.bazel
+++ b/foreign/cpp/MODULE.bazel
@@ -47,6 +47,6 @@ filegroup(
rust_host_tools = use_extension("@rules_rust//rust:extensions.bzl",
"rust_host_tools")
rust_host_tools.host_tools(
name = "rs_host_tools",
- version = "1.98.0",
+ version = "1.99.0",
)
use_repo(rust_host_tools, "rs_host_tools")
diff --git a/foreign/php/Dockerfile.test b/foreign/php/Dockerfile.test
index e5ce15a7d..3684c2eaf 100644
--- a/foreign/php/Dockerfile.test
+++ b/foreign/php/Dockerfile.test
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
FROM rust:${RUST_VERSION}-slim-trixie
RUN apt-get update && apt-get install -y --no-install-recommends \
diff --git a/gateways/kafka/Dockerfile b/gateways/kafka/Dockerfile
index d5d95eb68..63fa36aed 100644
--- a/gateways/kafka/Dockerfile
+++ b/gateways/kafka/Dockerfile
@@ -18,7 +18,7 @@
# Build context is the repository root (a Cargo workspace member cannot build
standalone) -
# `docker-compose.yml` in this directory sets `context: ../..` accordingly.
-ARG RUST_VERSION=1.98
+ARG RUST_VERSION=1.99
FROM rust:${RUST_VERSION}-slim-trixie AS builder
WORKDIR /build
diff --git a/gateways/kafka/src/protocol/acl.rs
b/gateways/kafka/src/protocol/acl.rs
index a421ed202..6e707f0de 100644
--- a/gateways/kafka/src/protocol/acl.rs
+++ b/gateways/kafka/src/protocol/acl.rs
@@ -359,7 +359,7 @@ mod tests {
#[test]
fn given_no_permissions_when_rendered_should_produce_no_bindings() {
- assert!(bindings_for(&PrincipalPermissions::default()).is_empty());
+ assert_eq!(bindings_for(&PrincipalPermissions::default()), []);
}
#[test]
@@ -595,6 +595,6 @@ mod tests {
.iter()
.all(|binding| binding.resource_type == resource_type::CLUSTER)
);
- assert!(!selected.is_empty());
+ assert_ne!(selected, []);
}
}
diff --git a/gateways/kafka/src/protocol/handlers/metadata.rs
b/gateways/kafka/src/protocol/handlers/metadata.rs
index 69685d9ac..bfa6aea7f 100644
--- a/gateways/kafka/src/protocol/handlers/metadata.rs
+++ b/gateways/kafka/src/protocol/handlers/metadata.rs
@@ -530,7 +530,7 @@ mod tests {
// malformed request - must decode to an empty list.
let body = Bytes::from_static(&[0xff, 0xff, 0xff, 0xff]); // -1
let topics = decode_topics(0, body, TEST_MAX_FRAME_SIZE).unwrap();
- assert!(topics.is_empty());
+ assert_eq!(topics, [] as [StrBytes; 0]);
}
#[test]
diff --git a/gateways/kafka/tests/bridge_iggy_integration_tests.rs
b/gateways/kafka/tests/bridge_iggy_integration_tests.rs
index d315db7f8..51af8ba70 100644
--- a/gateways/kafka/tests/bridge_iggy_integration_tests.rs
+++ b/gateways/kafka/tests/bridge_iggy_integration_tests.rs
@@ -785,7 +785,7 @@ async fn list_kafka_topics_is_empty_when_nothing_exists() {
.list_kafka_topics()
.await
.expect("listing against a nonexistent default stream must not error");
- assert!(topics.is_empty());
+ assert_eq!(topics, []);
}
#[tokio::test]
diff --git a/gateways/kafka/tests/consumer_group_tests.rs
b/gateways/kafka/tests/consumer_group_tests.rs
index cb10c6608..89cc7087c 100644
--- a/gateways/kafka/tests/consumer_group_tests.rs
+++ b/gateways/kafka/tests/consumer_group_tests.rs
@@ -392,10 +392,10 @@ async fn
given_an_empty_member_id_when_joining_at_v9_should_require_a_member_id(
let response = join(&state, 9, &join_params("", protocols)).await;
assert_eq!(response.error, ERROR_MEMBER_ID_REQUIRED);
- assert!(!response.member_id.is_empty());
+ assert_ne!(response.member_id, "");
assert_eq!(response.generation_id, -1);
- assert!(response.leader.is_empty());
- assert!(response.members.is_empty());
+ assert_eq!(response.leader, "");
+ assert_eq!(response.members, []);
assert_eq!(
response.protocol_name, None,
"v9 encodes an absent protocol name as null"
@@ -426,7 +426,7 @@ async fn
given_an_empty_member_id_when_joining_at_v3_should_admit_the_member_dir
assert_eq!(response.error, ERROR_NONE);
assert_eq!(response.generation_id, 1);
- assert!(!response.member_id.is_empty());
+ assert_ne!(response.member_id, "");
assert_eq!(response.leader, response.member_id);
assert_eq!(response.protocol_name.as_deref(), Some("range"));
assert_eq!(response.members.len(), 1);
@@ -1459,7 +1459,7 @@ async fn
given_two_tcp_clients_when_they_join_and_sync_should_each_receive_their
assert_eq!(rejoined.members.len(), 2);
let follower_join = read_join(&mut follower_stream).await;
assert_eq!(follower_join.generation_id, 2);
- assert!(follower_join.members.is_empty());
+ assert_eq!(follower_join.members, []);
write_request(
&mut follower_stream,
diff --git a/gateways/kafka/tests/fetch_real_bridge_tests.rs
b/gateways/kafka/tests/fetch_real_bridge_tests.rs
index 1340aedad..80281b45e 100644
--- a/gateways/kafka/tests/fetch_real_bridge_tests.rs
+++ b/gateways/kafka/tests/fetch_real_bridge_tests.rs
@@ -296,7 +296,7 @@ fn values(partition: &PartitionData) -> Vec<Option<Bytes>> {
fn assert_refused(partition: &PartitionData, code: i16) {
assert_eq!(partition.error_code, code);
assert_eq!(partition.high_watermark, UNKNOWN_OFFSET);
- assert!(records(partition).is_empty());
+ assert_eq!(records(partition), []);
}
#[tokio::test]
@@ -484,7 +484,7 @@ async fn
given_offset_at_high_watermark_when_fetching_should_wait_and_return_emp
let partition = only(&response);
assert_eq!(partition.error_code, ERROR_NONE);
assert_eq!(partition.high_watermark, 2);
- assert!(records(partition).is_empty());
+ assert_eq!(records(partition), []);
}
#[tokio::test]
@@ -587,7 +587,7 @@ async fn
given_zero_max_wait_when_fetching_should_answer_at_once() {
let partition = only(&response);
assert_eq!(partition.error_code, ERROR_NONE);
assert_eq!(partition.high_watermark, 0);
- assert!(records(partition).is_empty());
+ assert_eq!(records(partition), []);
}
}
@@ -631,7 +631,7 @@ async fn
given_an_empty_partition_when_fetching_past_it_should_answer_6_after_th
let response = fetch(&state, &at_start).await;
let partition = only(&response);
assert_eq!(partition.error_code, ERROR_NONE, "caught up, not refused");
- assert!(records(partition).is_empty());
+ assert_eq!(records(partition), []);
}
#[tokio::test]
diff --git a/gateways/kafka/tests/metadata_real_bridge_tests.rs
b/gateways/kafka/tests/metadata_real_bridge_tests.rs
index cccced5ef..86ea39e7f 100644
--- a/gateways/kafka/tests/metadata_real_bridge_tests.rs
+++ b/gateways/kafka/tests/metadata_real_bridge_tests.rs
@@ -249,7 +249,7 @@ async fn
a_null_topics_array_against_an_empty_bridge_lists_nothing() {
let (state, _seed) = connected_state(&server).await;
let topics = send(&state, None).await;
- assert!(topics.is_empty());
+ assert_eq!(topics, []);
}
#[tokio::test]
diff --git a/gateways/kafka/tests/produce_real_bridge_tests.rs
b/gateways/kafka/tests/produce_real_bridge_tests.rs
index 5ad6d66f1..1db4ee69f 100644
--- a/gateways/kafka/tests/produce_real_bridge_tests.rs
+++ b/gateways/kafka/tests/produce_real_bridge_tests.rs
@@ -383,7 +383,7 @@ async fn
given_two_batches_in_one_blob_when_handled_should_answer_invalid_record
produce(&state, 3, 1, TOPIC, &entries).await,
vec![(0, ERROR_INVALID_RECORD, -1)]
);
- assert!(stored(&server, 0, 10).await.is_empty());
+ assert_eq!(stored(&server, 0, 10).await, []);
}
#[tokio::test]
diff --git a/gateways/kafka/tests/server_e2e_tests.rs
b/gateways/kafka/tests/server_e2e_tests.rs
index d12764040..0cfcd3264 100644
--- a/gateways/kafka/tests/server_e2e_tests.rs
+++ b/gateways/kafka/tests/server_e2e_tests.rs
@@ -398,7 +398,7 @@ async fn
metadata_all_topics_null_array_e2e_returns_broker() {
assert_eq!(d.read_i32().unwrap(), 1, "one stub broker");
d.read_i32().unwrap(); // node_id
let host = d.read_nullable_string().unwrap().expect("broker host");
- assert!(!host.is_empty());
+ assert_ne!(host, "");
let port = d.read_i32().unwrap();
assert!(port > 0);
}
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index 05c70ae64..2e8ac3b8c 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -16,6 +16,6 @@
# under the License.
[toolchain]
-channel = "1.98.0"
+channel = "1.99.0"
components = ["rustfmt", "clippy"]
profile = "default"