From 48a1083fb2928087988d4889dc02ea8702d07fdc Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Tue, 4 Aug 2026 11:07:58 +0100 Subject: [PATCH 1/3] Bump Rust to 1.97.1 and the CI nightly to 2026-08-02 The nightly deliberately stops at 2026-08-02 rather than tracking the latest. The 2026-08-03 nightly regressed the `visible_parent_map` query so that rustdoc allocates without bound and gets OOM-killed on crates with large dependency graphs, which breaks the Doctests job. See https://github.com/rust-lang/rust/issues/160439. --- Cargo.toml | 2 +- bin/ci-builder | 5 ++++- bin/lint-versions | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b4637aeb02f63..a581d55e26722 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -269,7 +269,7 @@ resolver = "3" [workspace.package] edition = "2024" -rust-version = "1.96.0" +rust-version = "1.97.1" [workspace.dependencies] ahash = { version = "0.8.12", default-features = false } diff --git a/bin/ci-builder b/bin/ci-builder index f08e03dede7ed..da284dafabfdf 100755 --- a/bin/ci-builder +++ b/bin/ci-builder @@ -16,7 +16,10 @@ set -euo pipefail -NIGHTLY_RUST_DATE=2026-06-01 +# NOTE: The 2026-08-03 nightly makes rustdoc run out of memory, which breaks the +# Doctests job. Do not advance past 2026-08-02 until that is fixed. +# See https://github.com/rust-lang/rust/issues/160439. +NIGHTLY_RUST_DATE=2026-08-02 workdir=$(pwd) cd "$(dirname "$0")/.." diff --git a/bin/lint-versions b/bin/lint-versions index 601db49dddb41..83c76b5bc6b33 100755 --- a/bin/lint-versions +++ b/bin/lint-versions @@ -11,5 +11,5 @@ # # lint-versions - Check rust version -grep "rust-version = " Cargo.toml | grep -q "1\.96\.0" || \ +grep "rust-version = " Cargo.toml | grep -q "1\.97\.1" || \ (echo "Please validate new Rust versions for compilation time performance regressions or ask Team Testing to do so. Afterwards change the tested version in bin/lint-versions" && exit 1) From 9e578076bb9d262423e5fc1b9d13b977cee4c846 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Tue, 4 Aug 2026 11:07:58 +0100 Subject: [PATCH 2/3] Fix clippy and rustdoc lints for Rust 1.97.1 Mostly needless borrows that the newer clippy now flags. Also allows `rustdoc::invalid_html_tags` in the Materialize CRD module. The doc comments there become the descriptions in the generated CRD, which the docs site renders through Hugo, so they contain shortcodes like `{{}}`. Rustdoc reads the inner `` as an HTML tag and reports it unclosed whenever a shortcode spans more than one Markdown paragraph. --- src/adapter/src/catalog/apply.rs | 4 +- src/adapter/src/coord/timestamp_selection.rs | 2 +- src/avro/src/reader.rs | 8 +- src/catalog-debug/src/main.rs | 4 +- src/cloud-resources/src/crd.rs | 2 +- src/cloud-resources/src/crd/materialize.rs | 7 ++ src/cloud-resources/src/crd/vpc_endpoint.rs | 2 +- src/compute-types/src/explain/text.rs | 8 +- src/compute/src/render.rs | 10 +-- src/environmentd/src/http/console.rs | 2 +- src/environmentd/src/lib.rs | 2 +- src/environmentd/tests/server.rs | 90 +++++++++---------- src/environmentd/tests/sql.rs | 4 +- src/frontegg-mock/src/server.rs | 2 +- src/mz-debug/src/k8s_dumper.rs | 3 +- src/mz-debug/src/kubectl_port_forwarder.rs | 2 +- src/mz-debug/src/main.rs | 2 +- .../src/controller/materialize.rs | 2 +- .../src/controller/materialize/generation.rs | 4 +- src/ore/src/str.rs | 11 +-- src/persist-client/src/internal/gc.rs | 2 +- src/persist-client/src/internal/machine.rs | 4 +- src/persist-client/src/internal/state.rs | 4 +- src/persist-client/src/internal/state_diff.rs | 8 +- src/persist/src/indexed/encoding.rs | 6 +- src/postgres-util/src/replication.rs | 2 +- src/sql-server-util/src/cdc.rs | 4 +- src/sql/src/func.rs | 2 +- src/sql/src/plan.rs | 4 +- src/storage-types/src/connections/aws.rs | 2 +- src/storage/src/sink/kafka.rs | 4 +- src/storage/src/source/mysql/snapshot.rs | 8 +- .../src/source/sql_server/replication.rs | 4 +- src/testdrive/src/action/mysql/execute.rs | 2 +- src/testdrive/src/action/postgres/execute.rs | 2 +- .../src/action/postgres/verify_slot.rs | 4 +- 36 files changed, 118 insertions(+), 115 deletions(-) diff --git a/src/adapter/src/catalog/apply.rs b/src/adapter/src/catalog/apply.rs index cd1a23f721ae6..0b70c7d72c847 100644 --- a/src/adapter/src/catalog/apply.rs +++ b/src/adapter/src/catalog/apply.rs @@ -2020,7 +2020,7 @@ impl CatalogState { Some(metadata) => metadata.referenced_by.push(entry.id()), None => panic!( "Catalog: missing dependent catalog item {} while installing {}", - &u, + u, self.resolve_full_name(entry.name(), entry.conn_id()) ), } @@ -2035,7 +2035,7 @@ impl CatalogState { Some(metadata) => metadata.used_by.push(entry.id()), None => panic!( "Catalog: missing dependent catalog item {} while installing {}", - &u, + u, self.resolve_full_name(entry.name(), entry.conn_id()) ), } diff --git a/src/adapter/src/coord/timestamp_selection.rs b/src/adapter/src/coord/timestamp_selection.rs index 6ee6de1738cc7..29cad365aefa3 100644 --- a/src/adapter/src/coord/timestamp_selection.rs +++ b/src/adapter/src/coord/timestamp_selection.rs @@ -943,7 +943,7 @@ impl fmt::Display for TimestampExplanation { " can respond immediately: {}", self.respond_immediately )?; - writeln!(f, " timeline: {:?}", &timeline)?; + writeln!(f, " timeline: {:?}", timeline)?; writeln!( f, " session wall time: {:13} ({})", diff --git a/src/avro/src/reader.rs b/src/avro/src/reader.rs index 03a86a065ef07..f2bb1a7e2b402 100644 --- a/src/avro/src/reader.rs +++ b/src/avro/src/reader.rs @@ -525,7 +525,7 @@ impl<'a> SchemaResolver<'a> { } else { return Err(SchemaResolutionError::new(format!( "Fixed schema {:?}: sizes don't match ({}, {}) for field `{}`", - &rs.name, + rs.name, wsz, rsz, self.get_current_human_readable_path(), @@ -548,7 +548,7 @@ impl<'a> SchemaResolver<'a> { if wp != rp { return Err(SchemaResolutionError::new(format!( "Decimal schema {:?}: precisions don't match: {}, {} for field `{}`", - &rs.name, + rs.name, wp, rp, self.get_current_human_readable_path(), @@ -558,7 +558,7 @@ impl<'a> SchemaResolver<'a> { if wscale != rscale { return Err(SchemaResolutionError::new(format!( "Decimal schema {:?}: sizes don't match: {}, {} for field `{}`", - &rs.name, + rs.name, wscale, rscale, self.get_current_human_readable_path(), @@ -568,7 +568,7 @@ impl<'a> SchemaResolver<'a> { if wsz != rsz { return Err(SchemaResolutionError::new(format!( "Decimal schema {:?}: sizes don't match: {:?}, {:?} for field `{}`", - &rs.name, + rs.name, wsz, rsz, self.get_current_human_readable_path(), diff --git a/src/catalog-debug/src/main.rs b/src/catalog-debug/src/main.rs index 7f48ed56f2810..b00571e64a20f 100644 --- a/src/catalog-debug/src/main.rs +++ b/src/catalog-debug/src/main.rs @@ -710,7 +710,7 @@ async fn upgrade_check( let msg = format!( "catalog upgrade from {} to {} would succeed in about {} ms", last_seen_version, - &BUILD_INFO.human_version(None), + BUILD_INFO.human_version(None), dur.as_millis(), ); println!("{msg}"); @@ -839,6 +839,6 @@ struct UnescapedDebug(String); impl std::fmt::Debug for UnescapedDebug { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "'{}'", &self.0) + write!(f, "'{}'", self.0) } } diff --git a/src/cloud-resources/src/crd.rs b/src/cloud-resources/src/crd.rs index a59b5e188aa31..b1a828d3d4d91 100644 --- a/src/cloud-resources/src/crd.rs +++ b/src/cloud-resources/src/crd.rs @@ -178,7 +178,7 @@ async fn register_custom_resource( field_manager: &str, ) -> Result<(), anyhow::Error> { let crds = versioned_crds.crds; - let crd_name = format!("{}.{}", &crds[0].spec.names.plural, &crds[0].spec.group); + let crd_name = format!("{}.{}", crds[0].spec.names.plural, crds[0].spec.group); info!("Registering {} crd", &crd_name); let crd_api = Api::::all(kube_client); let mut crd = merge_crds(crds, &versioned_crds.stored_version).unwrap(); diff --git a/src/cloud-resources/src/crd/materialize.rs b/src/cloud-resources/src/crd/materialize.rs index a4a1479b41646..714b1c43963c8 100644 --- a/src/cloud-resources/src/crd/materialize.rs +++ b/src/cloud-resources/src/crd/materialize.rs @@ -7,6 +7,13 @@ // the Business Source License, use of this software will be governed // by the Apache License, Version 2.0. +// The doc comments here become the descriptions in the generated CRD, which the +// docs site renders through Hugo, so they contain shortcodes like +// `{{}}`. Rustdoc reads the inner `` as an HTML tag and +// reports it unclosed whenever a shortcode spans more than one Markdown +// paragraph. +#![allow(rustdoc::invalid_html_tags)] + use std::collections::BTreeMap; use std::time::Duration; diff --git a/src/cloud-resources/src/crd/vpc_endpoint.rs b/src/cloud-resources/src/crd/vpc_endpoint.rs index eede3e64d9af1..04240f9306bb1 100644 --- a/src/cloud-resources/src/crd/vpc_endpoint.rs +++ b/src/cloud-resources/src/crd/vpc_endpoint.rs @@ -195,7 +195,7 @@ mod tests { assert_eq!( &crd_json, exported_crd_json, "VpcEndpoint CRD json does not match exported json.\n\nCRD:\n{}\n\nExported CRD:\n{}", - &crd_json, exported_crd_json, + crd_json, exported_crd_json, ); } } diff --git a/src/compute-types/src/explain/text.rs b/src/compute-types/src/explain/text.rs index f811feca50105..ae1a38a73b6a8 100644 --- a/src/compute-types/src/explain/text.rs +++ b/src/compute-types/src/explain/text.rs @@ -1319,13 +1319,13 @@ impl LinearJoinPlan { writeln!( f, "{}source={{ relation={}, key=[{}] }}", - ctx.indent, &plan.source_relation, source_key + ctx.indent, plan.source_relation, source_key )? } None => writeln!( f, "{}source={{ relation={}, raw }}", - ctx.indent, &plan.source_relation + ctx.indent, plan.source_relation )?, }; Ok(()) @@ -1523,13 +1523,13 @@ impl DeltaPathPlan { writeln!( f, "{}source={{ relation={}, key=[{}] }}", - ctx.indent, &plan.source_relation, source_key + ctx.indent, plan.source_relation, source_key )? } None => writeln!( f, "{}source={{ relation={}, raw }}", - ctx.indent, &plan.source_relation + ctx.indent, plan.source_relation )?, }; Ok(()) diff --git a/src/compute/src/render.rs b/src/compute/src/render.rs index 15305e304099b..82fc821cd8604 100644 --- a/src/compute/src/render.rs +++ b/src/compute/src/render.rs @@ -232,9 +232,9 @@ pub fn build_compute_dataflow( let subscribe_snapshot_optimization = SUBSCRIBE_SNAPSHOT_OPTIMIZATION.get(&compute_state.worker_config); - let name = format!("Dataflow: {}", &dataflow.debug_name); - let input_name = format!("InputRegion: {}", &dataflow.debug_name); - let build_name = format!("BuildRegion: {}", &dataflow.debug_name); + let name = format!("Dataflow: {}", dataflow.debug_name); + let input_name = format!("InputRegion: {}", dataflow.debug_name); + let build_name = format!("BuildRegion: {}", dataflow.debug_name); timely_worker.dataflow_core(&name, worker_logging, Box::new(()), |_, scope| { let scope = scope.with_label(); @@ -751,7 +751,7 @@ impl<'g> Context<'g, mz_repr::Timestamp> { panic!( "Arrangement alarmingly absent! id: {:?}, keys: {:?}", Id::Global(idx_id), - &key + key ); } }; @@ -853,7 +853,7 @@ where panic!( "Arrangement alarmingly absent! id: {:?}, keys: {:?}", Id::Global(idx_id), - &key, + key, ); } }; diff --git a/src/environmentd/src/http/console.rs b/src/environmentd/src/http/console.rs index f212edd79852b..4dbdebf4c5425 100644 --- a/src/environmentd/src/http/console.rs +++ b/src/environmentd/src/http/console.rs @@ -109,7 +109,7 @@ pub(crate) async fn handle_internal_console( path_query = stripped_path_query; } - let uri = Uri::try_from(format!("{}{}", &console_config.url, path_query)).unwrap(); + let uri = Uri::try_from(format!("{}{}", console_config.url, path_query)).unwrap(); let host = uri.host().unwrap().to_string(); // Preserve the request, but update the URI to point upstream. *req.uri_mut() = uri; diff --git a/src/environmentd/src/lib.rs b/src/environmentd/src/lib.rs index 259bbf895ac4a..bef2349b25938 100644 --- a/src/environmentd/src/lib.rs +++ b/src/environmentd/src/lib.rs @@ -319,7 +319,7 @@ impl Listener { impl Listener { #[instrument(name = "environmentd::serve_http")] pub async fn serve_http(self, config: HttpConfig) -> ListenerHandle { - let task_name = format!("{}_http_server", &config.source); + let task_name = format!("{}_http_server", config.source); task::spawn(|| task_name, { let http_server = HttpServer::new(config); mz_server_core::serve(ServeConfig { diff --git a/src/environmentd/tests/server.rs b/src/environmentd/tests/server.rs index b62f4795694b5..9ea6298a9d86b 100644 --- a/src/environmentd/tests/server.rs +++ b/src/environmentd/tests/server.rs @@ -107,7 +107,7 @@ fn test_persistence() { client .batch_execute(&format!( "CREATE CONNECTION kafka_conn TO KAFKA (BROKER '{}', SECURITY PROTOCOL PLAINTEXT)", - &*KAFKA_ADDRS, + *KAFKA_ADDRS, )) .unwrap(); client @@ -1186,30 +1186,30 @@ fn test_http_sql() { .connect(postgres::NoTls) .unwrap(); super_user - .batch_execute(&format!("CREATE ROLE {}", &HTTP_DEFAULT_USER.name)) + .batch_execute(&format!("CREATE ROLE {}", HTTP_DEFAULT_USER.name)) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SYSTEM TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON CLUSTER quickstart TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON DATABASE materialize TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SCHEMA materialize.public TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); } @@ -5421,30 +5421,30 @@ fn run_mcp_datadriven_inner( .connect(postgres::NoTls) .unwrap(); super_user - .batch_execute(&format!("CREATE ROLE {}", &HTTP_DEFAULT_USER.name)) + .batch_execute(&format!("CREATE ROLE {}", HTTP_DEFAULT_USER.name)) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SYSTEM TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON CLUSTER quickstart TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON DATABASE materialize TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SCHEMA materialize.public TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); @@ -5458,7 +5458,7 @@ fn run_mcp_datadriven_inner( super_user .batch_execute(&format!( "ALTER ROLE {} SET restrict_to_user_objects = true", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); } @@ -5715,24 +5715,24 @@ fn test_mcp_developer_search_path_defense() { .unwrap(); super_user - .batch_execute(&format!("CREATE ROLE {}", &HTTP_DEFAULT_USER.name)) + .batch_execute(&format!("CREATE ROLE {}", HTTP_DEFAULT_USER.name)) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SYSTEM TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON DATABASE materialize TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SCHEMA materialize.public TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); @@ -5749,13 +5749,13 @@ fn test_mcp_developer_search_path_defense() { super_user .batch_execute(&format!( "GRANT SELECT ON public.mz_leak, public.pg_leak TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "ALTER ROLE {} SET search_path TO public", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); } @@ -5915,30 +5915,30 @@ fn test_mcp_developer_rbac_passthrough() { .batch_execute("ALTER SYSTEM SET enable_rbac_checks TO true") .unwrap(); super_user - .batch_execute(&format!("CREATE ROLE {}", &HTTP_DEFAULT_USER.name)) + .batch_execute(&format!("CREATE ROLE {}", HTTP_DEFAULT_USER.name)) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SYSTEM TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON DATABASE materialize TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SCHEMA materialize.public TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON CLUSTER quickstart TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); @@ -6061,7 +6061,7 @@ fn test_mcp_developer_rbac_passthrough() { super_user .batch_execute(&format!( "GRANT USAGE ON SCHEMA restricted_schema TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); } @@ -6094,7 +6094,7 @@ fn test_mcp_developer_rbac_passthrough() { super_user .batch_execute(&format!( "GRANT SELECT ON restricted_schema.v TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); } @@ -6112,7 +6112,7 @@ fn test_mcp_developer_rbac_passthrough() { super_user .batch_execute(&format!( "REVOKE USAGE ON SCHEMA restricted_schema FROM {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); } @@ -6212,30 +6212,30 @@ fn test_mcp_agent_with_data_product() { // Create the HTTP user and grant privileges. super_user - .batch_execute(&format!("CREATE ROLE {}", &HTTP_DEFAULT_USER.name)) + .batch_execute(&format!("CREATE ROLE {}", HTTP_DEFAULT_USER.name)) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SYSTEM TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON CLUSTER quickstart TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON DATABASE materialize TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SCHEMA materialize.public TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); @@ -6258,14 +6258,14 @@ fn test_mcp_agent_with_data_product() { super_user .batch_execute(&format!( "GRANT SELECT ON test_products TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); // Grant USAGE on the cluster so it appears in mz_show_my_cluster_privileges. super_user .batch_execute(&format!( "GRANT USAGE ON CLUSTER quickstart TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); @@ -6288,7 +6288,7 @@ fn test_mcp_agent_with_data_product() { super_user .batch_execute(&format!( "GRANT SELECT ON test_indexed_view TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); @@ -6302,7 +6302,7 @@ fn test_mcp_agent_with_data_product() { super_user .batch_execute(&format!( "GRANT SELECT ON test_unindexed_view TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); @@ -6322,7 +6322,7 @@ fn test_mcp_agent_with_data_product() { super_user .batch_execute(&format!( "GRANT SELECT ON test_unindexed_mv TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); } @@ -6589,13 +6589,13 @@ fn test_mcp_agent_with_data_product() { super_user .batch_execute(&format!( "GRANT SELECT ON test_off_default TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT USAGE ON CLUSTER dex27_other_cluster TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); } @@ -7455,24 +7455,24 @@ fn test_mcp_agent_rbac() { // Create the HTTP default user with basic system/database/schema privileges // but NO object-level grants yet. super_user - .batch_execute(&format!("CREATE ROLE {}", &HTTP_DEFAULT_USER.name)) + .batch_execute(&format!("CREATE ROLE {}", HTTP_DEFAULT_USER.name)) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SYSTEM TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON DATABASE materialize TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); super_user .batch_execute(&format!( "GRANT ALL PRIVILEGES ON SCHEMA materialize.public TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); @@ -7518,7 +7518,7 @@ fn test_mcp_agent_rbac() { super_user .batch_execute(&format!( "GRANT SELECT ON rbac_product TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); let (status, body) = mcp_post(&agents_url, get_products.clone()); @@ -7551,7 +7551,7 @@ fn test_mcp_agent_rbac() { super_user .batch_execute(&format!( "REVOKE SELECT ON rbac_product FROM {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); let (status, body) = mcp_post(&agents_url, get_products.clone()); @@ -7584,7 +7584,7 @@ fn test_mcp_agent_rbac() { super_user .batch_execute(&format!( "GRANT SELECT ON rbac_product TO {}", - &HTTP_DEFAULT_USER.name + HTTP_DEFAULT_USER.name )) .unwrap(); let (status, body) = mcp_post(&agents_url, get_products.clone()); diff --git a/src/environmentd/tests/sql.rs b/src/environmentd/tests/sql.rs index 6e891c8b1b85b..ac74a7be27548 100644 --- a/src/environmentd/tests/sql.rs +++ b/src/environmentd/tests/sql.rs @@ -157,7 +157,7 @@ async fn test_no_block() { let result = client .batch_execute(&format!( "CREATE CONNECTION kafka_conn TO KAFKA (BROKER '{}', SECURITY PROTOCOL PLAINTEXT) WITH (VALIDATE = false)", - &*KAFKA_ADDRS, + *KAFKA_ADDRS, )) .await; println!("test_no_block: in thread; create Kafka conn done"); @@ -237,7 +237,7 @@ async fn test_drop_connection_race() { client .batch_execute(&format!( "CREATE CONNECTION kafka_conn TO KAFKA (BROKER '{}', SECURITY PROTOCOL PLAINTEXT) WITH (VALIDATE = false)", - &*KAFKA_ADDRS, + *KAFKA_ADDRS, )) .await .unwrap(); diff --git a/src/frontegg-mock/src/server.rs b/src/frontegg-mock/src/server.rs index d8213e18ef3e6..63996528ac21e 100644 --- a/src/frontegg-mock/src/server.rs +++ b/src/frontegg-mock/src/server.rs @@ -298,7 +298,7 @@ impl FronteggMockServer { } pub fn auth_api_token_url(&self) -> String { - format!("{}{}", &self.base_url, AUTH_API_TOKEN_PATH) + format!("{}{}", self.base_url, AUTH_API_TOKEN_PATH) } } diff --git a/src/mz-debug/src/k8s_dumper.rs b/src/mz-debug/src/k8s_dumper.rs index f00a3e9345c3d..bc30124718040 100644 --- a/src/mz-debug/src/k8s_dumper.rs +++ b/src/mz-debug/src/k8s_dumper.rs @@ -98,8 +98,7 @@ where for (i, item) in object_list.items.iter().enumerate() { let file_name = file_path.join(format!( "{}.yaml", - &item - .meta() + item.meta() .name .clone() .unwrap_or_else(|| format!("unknown_{}", i)) diff --git a/src/mz-debug/src/kubectl_port_forwarder.rs b/src/mz-debug/src/kubectl_port_forwarder.rs index 3b9a938aa25b2..0a0e114b37559 100644 --- a/src/mz-debug/src/kubectl_port_forwarder.rs +++ b/src/mz-debug/src/kubectl_port_forwarder.rs @@ -79,7 +79,7 @@ impl KubectlPortForwarder { /// Spawns a port forwarding process that resolves when /// the port forward is established. pub async fn spawn_port_forward(&self) -> Result { - let port_arg_str = format!(":{}", &self.target_port); + let port_arg_str = format!(":{}", self.target_port); let target_arg_str = self.target.kubectl_arg(); let mut args = vec![ "port-forward", diff --git a/src/mz-debug/src/main.rs b/src/mz-debug/src/main.rs index 1aa02a2b716da..0b9d089534135 100644 --- a/src/mz-debug/src/main.rs +++ b/src/mz-debug/src/main.rs @@ -518,7 +518,7 @@ async fn run(context: Context) -> Result<(), anyhow::Error> { info!("Zipping debug directory"); - let zip_file_name = format!("{}.zip", &context.base_path.display()); + let zip_file_name = format!("{}.zip", context.base_path.display()); if let Err(e) = zip_debug_folder(PathBuf::from(&zip_file_name), &context.base_path) { warn!("Failed to zip debug directory: {:#}", e); diff --git a/src/orchestratord/src/controller/materialize.rs b/src/orchestratord/src/controller/materialize.rs index 823ba5ba0282c..c19b0935106ad 100644 --- a/src/orchestratord/src/controller/materialize.rs +++ b/src/orchestratord/src/controller/materialize.rs @@ -506,7 +506,7 @@ impl k8s_controller::Context for Context { first.", last_completed_rollout_environmentd_image_ref .expect("should be set if upgrade window check fails"), - &mz.spec.environmentd_image_ref, + mz.spec.environmentd_image_ref, ), observed_generation: mz.meta().generation, reason: "FailedDeploy".into(), diff --git a/src/orchestratord/src/controller/materialize/generation.rs b/src/orchestratord/src/controller/materialize/generation.rs index c94e0b3941faa..08b217364b7ba 100644 --- a/src/orchestratord/src/controller/materialize/generation.rs +++ b/src/orchestratord/src/controller/materialize/generation.rs @@ -763,7 +763,7 @@ fn create_environmentd_statefulset_object( "--orchestrator=kubernetes".into(), format!( "--orchestrator-kubernetes-service-account={}", - &mz.service_account_name() + mz.service_account_name() ), format!( "--orchestrator-kubernetes-image-pull-policy={}", @@ -942,7 +942,7 @@ fn create_environmentd_statefulset_object( // Add URL for internal user impersonation endpoint args.push(format!( "--internal-console-redirect-url={}", - &config.internal_console_proxy_url, + config.internal_console_proxy_url, )); if !config.collect_pod_metrics { diff --git a/src/ore/src/str.rs b/src/ore/src/str.rs index a2121add7438d..39031eecb5fd3 100644 --- a/src/ore/src/str.rs +++ b/src/ore/src/str.rs @@ -469,7 +469,7 @@ impl Debug for Redacting { } else { f.write_char('<')?; let mut write = RedactingWriter(f); - write!(&mut write, "{:?}", &self.value)?; + write!(&mut write, "{:?}", self.value)?; f.write_char('>') } } @@ -506,12 +506,9 @@ mod tests { assert_eq!( r#"<"XXXX_XXXXXX">"#, - format!("{:?}", &redact(&"TEST_STRING")) + format!("{:?}", redact(&"TEST_STRING")) ); - assert_eq!( - r#""TEST_STRING""#, - format!("{:#?}", &redact(&"TEST_STRING")) - ); - assert_eq!("<#.###>", format!("{:?}", &redact(&1.234f32))); + assert_eq!(r#""TEST_STRING""#, format!("{:#?}", redact(&"TEST_STRING"))); + assert_eq!("<#.###>", format!("{:?}", redact(&1.234f32))); } } diff --git a/src/persist-client/src/internal/gc.rs b/src/persist-client/src/internal/gc.rs index 63a49ce62e090..ccfdfa7fd6bcd 100644 --- a/src/persist-client/src/internal/gc.rs +++ b/src/persist-client/src/internal/gc.rs @@ -159,7 +159,7 @@ where let start = Instant::now(); machine.applier.metrics.gc.started.inc(); let (mut maintenance, _stats) = { - let name = format!("gc_and_truncate ({})", &consolidated_req.shard_id); + let name = format!("gc_and_truncate ({})", consolidated_req.shard_id); let machine = machine.clone(); isolated_runtime .spawn_named(|| name, async move { diff --git a/src/persist-client/src/internal/machine.rs b/src/persist-client/src/internal/machine.rs index 4eeeb8fd87101..964122851cec1 100644 --- a/src/persist-client/src/internal/machine.rs +++ b/src/persist-client/src/internal/machine.rs @@ -586,8 +586,8 @@ where assert!( PartialOrder::less_equal(&writer_upper, &shard_upper), "{:?} vs {:?}", - &writer_upper, - &shard_upper + writer_upper, + shard_upper ); if PartialOrder::less_than(&writer_upper, batch.desc.upper()) { // No way this could have committed in some previous diff --git a/src/persist-client/src/internal/state.rs b/src/persist-client/src/internal/state.rs index d19ba2247cf9a..176bcc9fb7c57 100644 --- a/src/persist-client/src/internal/state.rs +++ b/src/persist-client/src/internal/state.rs @@ -1161,7 +1161,7 @@ impl HollowBatch { return Err(format!( "batch since {:?} != minimum antichain {:?}", self.desc.since().elements(), - &[T::minimum()], + [T::minimum()], )); } for part in self.parts.iter() { @@ -1853,7 +1853,7 @@ where assert!( PartialOrder::less_equal(&writer_state.most_recent_write_upper, batch.desc.upper()), "{:?} vs {:?}", - &writer_state.most_recent_write_upper, + writer_state.most_recent_write_upper, batch.desc.upper() ); writer_state diff --git a/src/persist-client/src/internal/state_diff.rs b/src/persist-client/src/internal/state_diff.rs index 96985586a979e..fe68dd623f2b2 100644 --- a/src/persist-client/src/internal/state_diff.rs +++ b/src/persist-client/src/internal/state_diff.rs @@ -512,7 +512,7 @@ impl State { return Err(format!( "since update didn't match: {:?} vs {:?}", self.collections.trace.since(), - &from + from )); } trace.downgrade_since(&to); @@ -588,7 +588,7 @@ fn apply_diff_single_option( if single.as_ref() != Some(&from) { return Err(format!( "{} update didn't match: {:?} vs {:?}", - name, single, &from + name, single, from )); } *single = Some(to) @@ -603,7 +603,7 @@ fn apply_diff_single_option( if single.as_ref() != Some(&from) { return Err(format!( "{} delete didn't match: {:?} vs {:?}", - name, single, &from + name, single, from )); } *single = None @@ -633,7 +633,7 @@ fn apply_diff_single( if single != &from { return Err(format!( "{} update didn't match: {:?} vs {:?}", - name, single, &from + name, single, from )); } *single = to diff --git a/src/persist/src/indexed/encoding.rs b/src/persist/src/indexed/encoding.rs index e98255b3042dd..70ae0d14bc1e9 100644 --- a/src/persist/src/indexed/encoding.rs +++ b/src/persist/src/indexed/encoding.rs @@ -611,7 +611,7 @@ impl TraceBatchMeta { // useful/harmful. Feel free to make this a less_than if empty descs end // up making sense. if PartialOrder::less_equal(self.desc.upper(), self.desc.lower()) { - return Err(format!("invalid desc: {:?}", &self.desc).into()); + return Err(format!("invalid desc: {:?}", self.desc).into()); } Ok(()) @@ -633,7 +633,7 @@ impl TraceBatchMeta { if batch.desc != self.desc { return Err(format!( "invalid trace batch part desc expected {:?} got {:?}", - &self.desc, &batch.desc + self.desc, batch.desc ) .into()); } @@ -677,7 +677,7 @@ impl BlobTraceBatchPart { // useful/harmful. Feel free to make this a less_than if empty descs end // up making sense. if PartialOrder::less_equal(self.desc.upper(), self.desc.lower()) { - return Err(format!("invalid desc: {:?}", &self.desc).into()); + return Err(format!("invalid desc: {:?}", self.desc).into()); } let uncompacted = PartialOrder::less_equal(self.desc.since(), self.desc.lower()); diff --git a/src/postgres-util/src/replication.rs b/src/postgres-util/src/replication.rs index a4f7bc392d17c..947315bb14381 100644 --- a/src/postgres-util/src/replication.rs +++ b/src/postgres-util/src/replication.rs @@ -206,7 +206,7 @@ pub async fn drop_replication_slots( _ => { return Err(PostgresError::Generic(anyhow::anyhow!( "multiple pg_replication_slots entries for slot {}", - &slot + slot ))); } } diff --git a/src/sql-server-util/src/cdc.rs b/src/sql-server-util/src/cdc.rs index f4ba86cce2d93..9f87e0bd2e7be 100644 --- a/src/sql-server-util/src/cdc.rs +++ b/src/sql-server-util/src/cdc.rs @@ -171,8 +171,8 @@ impl<'a, M: SqlServerCdcMetrics> CdcStream<'a, M> { let mut fence_txn = fencing_client.transaction().await?; let qualified_table_name = format!( "{schema_name}.{table_name}", - schema_name = &table.schema_name, - table_name = &table.name + schema_name = table.schema_name, + table_name = table.name ); self.metrics .snapshot_table_lock_start(&qualified_table_name); diff --git a/src/sql/src/func.rs b/src/sql/src/func.rs index 6d9296a847b92..5152a8902c68d 100644 --- a/src/sql/src/func.rs +++ b/src/sql/src/func.rs @@ -1451,7 +1451,7 @@ impl PolymorphicSolution { assert_eq!( c, &compat_class, "do not know how to correlate polymorphic classes {:?} and {:?}", - c, &compat_class, + c, compat_class, ) } }; diff --git a/src/sql/src/plan.rs b/src/sql/src/plan.rs index a5981627894e2..69b62c5b552f1 100644 --- a/src/sql/src/plan.rs +++ b/src/sql/src/plan.rs @@ -1863,7 +1863,7 @@ impl TryFrom<&str> for NetworkPolicyRuleDirection { pub struct PolicyAddress(pub IpNet); impl std::fmt::Display for PolicyAddress { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", &self.0.to_string()) + write!(f, "{}", self.0) } } impl From for PolicyAddress { @@ -1885,7 +1885,7 @@ impl Serialize for PolicyAddress { where S: serde::Serializer, { - serializer.serialize_str(&format!("{}", &self.0)) + serializer.serialize_str(&format!("{}", self.0)) } } diff --git a/src/storage-types/src/connections/aws.rs b/src/storage-types/src/connections/aws.rs index ed119647c54b6..19c2016e68198 100644 --- a/src/storage-types/src/connections/aws.rs +++ b/src/storage-types/src/connections/aws.rs @@ -249,7 +249,7 @@ impl AwsAssumeRole { // The default session name identifies the environment and the // connection. let default_session_name = - format!("{}-{}", &connection_context.environment_id, connection_id); + format!("{}-{}", connection_context.environment_id, connection_id); // First we create a credentials provider that will assume the "jump // role" provided to this Materialize environment. This is the role that diff --git a/src/storage/src/sink/kafka.rs b/src/storage/src/sink/kafka.rs index 9bc469ad82e33..bdb8f916a7091 100644 --- a/src/storage/src/sink/kafka.rs +++ b/src/storage/src/sink/kafka.rs @@ -1252,8 +1252,8 @@ fn progress_search( { bail!( "upper regressed in topic {progress_topic}:{partition} from {:?} to {:?}", - &last_progress.frontier, - &progress.frontier, + last_progress.frontier, + progress.frontier, ); } _ => last_progress = Some(progress), diff --git a/src/storage/src/source/mysql/snapshot.rs b/src/storage/src/source/mysql/snapshot.rs index af8a5abc7859a..982efd6b15dbe 100644 --- a/src/storage/src/source/mysql/snapshot.rs +++ b/src/storage/src/source/mysql/snapshot.rs @@ -1311,7 +1311,7 @@ mod tests { assert_eq!( format!( "SELECT `c1`, `c2`, `c3` FROM `{}`.`{}`", - &schema_name, &table_name + schema_name, table_name ), query ); @@ -1358,7 +1358,7 @@ mod tests { assert_eq!( format!( "SELECT `id`, `name` FROM `{}`.`{}` WHERE `id` >= 100 AND `id` < 200", - &schema_name, &table_name + schema_name, table_name ), query ); @@ -1373,7 +1373,7 @@ mod tests { assert_eq!( format!( "SELECT `id`, `name` FROM `{}`.`{}` WHERE `id` < 200", - &schema_name, &table_name + schema_name, table_name ), query ); @@ -1388,7 +1388,7 @@ mod tests { assert_eq!( format!( "SELECT `id`, `name` FROM `{}`.`{}` WHERE `id` >= 200", - &schema_name, &table_name + schema_name, table_name ), query ); diff --git a/src/storage/src/source/sql_server/replication.rs b/src/storage/src/source/sql_server/replication.rs index 007290999a603..e908a008770d2 100644 --- a/src/storage/src/source/sql_server/replication.rs +++ b/src/storage/src/source/sql_server/replication.rs @@ -209,8 +209,8 @@ pub(crate) fn render<'scope>( // that we get exactly this many rows later. for table in &snapshot_tables { let qualified_table_name = format!("{schema_name}.{table_name}", - schema_name = &table.schema_name, - table_name = &table.name); + schema_name = table.schema_name, + table_name = table.name); let size_calc_start = Instant::now(); let table_total = mz_sql_server_util::inspect::snapshot_size( diff --git a/src/testdrive/src/action/mysql/execute.rs b/src/testdrive/src/action/mysql/execute.rs index a20ea978181dc..5c1bb23cfbd25 100644 --- a/src/testdrive/src/action/mysql/execute.rs +++ b/src/testdrive/src/action/mysql/execute.rs @@ -23,7 +23,7 @@ pub async fn run_execute( let conn = state .mysql_clients .get_mut(&name) - .ok_or_else(|| anyhow!("MySQL connection '{}' not found", &name))?; + .ok_or_else(|| anyhow!("MySQL connection '{}' not found", name))?; for query in cmd.input { println!(">> {}", query); diff --git a/src/testdrive/src/action/postgres/execute.rs b/src/testdrive/src/action/postgres/execute.rs index 6f89cc45f6f88..8e146e5bf4aa4 100644 --- a/src/testdrive/src/action/postgres/execute.rs +++ b/src/testdrive/src/action/postgres/execute.rs @@ -66,7 +66,7 @@ pub async fn run_execute( let client = state .postgres_clients .get(&connection) - .ok_or_else(|| anyhow!("connection '{}' not found", &connection))?; + .ok_or_else(|| anyhow!("connection '{}' not found", connection))?; execute_input(cmd, client).await?; } } diff --git a/src/testdrive/src/action/postgres/verify_slot.rs b/src/testdrive/src/action/postgres/verify_slot.rs index 4e3f9fdf0d769..92a642ff6f09a 100644 --- a/src/testdrive/src/action/postgres/verify_slot.rs +++ b/src/testdrive/src/action/postgres/verify_slot.rs @@ -33,7 +33,7 @@ pub async fn run_verify_slot( .initial_backoff(Duration::from_millis(50)) .max_duration(cmp::max(state.default_timeout, Duration::from_secs(60))) .retry_async_canceling(|_| async { - println!(">> checking for postgres replication slot {}", &slot); + println!(">> checking for postgres replication slot {}", slot); let rows = query( &client, sql!("SELECT active_pid FROM pg_replication_slots WHERE slot_name LIKE $1::TEXT"), @@ -45,7 +45,7 @@ pub async fn run_verify_slot( if rows.len() != 1 { bail!( "expected entry for slot {} in pg_replication slots, found {}", - &slot, + slot, rows.len() ); } From a157beae7687a8e8aa551096a3d6f5798f70662e Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Tue, 4 Aug 2026 11:07:58 +0100 Subject: [PATCH 3/3] bin/doc: Use the pinned CI nightly instead of the latest one A bare `+nightly` resolves to whatever the newest nightly is, so local doc builds drift from what CI tests and can pick up the very nightly regressions the pinned date exists to avoid. Read `NIGHTLY_RUST_DATE` out of `bin/ci-builder` instead, following the way that script already reads `rust-version` out of `Cargo.toml`. The toolchain is selected through `RUSTUP_TOOLCHAIN` rather than a `+toolchain` argument, which keeps the `cargo` invocations free of a variable that has to expand to no argument at all when CI supplies the nightly on the PATH itself. That also fixes the check guarding `--cfg nightly_doc_features`, which ran `cargo -V` against the default toolchain rather than the one the docs are built with, so it never fired locally. --- bin/doc | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/bin/doc b/bin/doc index 5093813b75634..7d0a1e5807b90 100755 --- a/bin/doc +++ b/bin/doc @@ -15,9 +15,9 @@ # of some unstable niceties, like the `doc_cfg` annotations to indicate in the # docs what features must be enabled to use an item. # -# CI always uses a nightly toolchain to run this script. To use one locally: -# -# $ RUSTUP_TOOLCHAIN=nightly bin/doc +# CI runs this script with a nightly toolchain already on the PATH. Run locally, +# it selects the same nightly that `bin/ci-builder` pins, so that local doc builds +# match what CI tests. # set -euo pipefail @@ -26,13 +26,16 @@ cd "$(dirname "$0")/.." . misc/shlib/shlib.bash -# The -Z flags are only available in nightly. If running locally using rustup proxy, -# add the +nightly flag, otherwise, assume the caller (CI) is using the correct -# binary. RUSTFLAGS and RUSTDOCFLAGS are toolchain variables, not rustup variables, so we -# need to pass flags via `cargo` -RUSTUP_FLAGS="" +# The -Z flags are only available in nightly. When running locally, `cargo` is the +# rustup proxy, so select the nightly through `RUSTUP_TOOLCHAIN`. In CI, `cargo` is +# the nightly binary itself and ignores that variable. if [[ -z "${CI+x}" || "$CI" != "true" ]] ; then - RUSTUP_FLAGS="+nightly" + # Pin to the same nightly CI uses. A bare `nightly` resolves to whatever the + # newest nightly is, which drifts from what CI tests and can pick up nightly + # regressions that the pinned date deliberately avoids. + nightly_date=$(sed -n 's/^NIGHTLY_RUST_DATE=\(.*\)$/\1/p' bin/ci-builder) + [[ -n "$nightly_date" ]] || die "could not read NIGHTLY_RUST_DATE from bin/ci-builder" + export RUSTUP_TOOLCHAIN="nightly-$nightly_date" fi RUSTDOCFLAGS+=" -D warnings " @@ -45,12 +48,12 @@ target=${CARGO_TARGET_DIR:-target} CARGO_DOC_OUTPUT=$(mktemp) # TODO: Remove -Zrustdoc-mergeable-info when https://github.com/rust-lang/rust/issues/146895 is fixed -if ! cargo $RUSTUP_FLAGS doc --all-features -Zrustdoc-mergeable-info "$@" 2> "$CARGO_DOC_OUTPUT"; then +if ! cargo doc --all-features -Zrustdoc-mergeable-info "$@" 2> "$CARGO_DOC_OUTPUT"; then if grep -q "invalid template" "$CARGO_DOC_OUTPUT"; then echo "Failed due to invalid template, nuking doc directory and retrying from scratch" rm -f "$CARGO_DOC_OUTPUT" rm -rf "$target"/doc - cargo $RUSTUP_FLAGS doc --all-features -Zrustdoc-mergeable-info "$@" + cargo doc --all-features -Zrustdoc-mergeable-info "$@" else echo "cargo doc failed:" cat "$CARGO_DOC_OUTPUT"