From fb10fbfb144f9b4e0c8427146f836a9e384dbf8b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 24 Jul 2026 15:33:40 +0000 Subject: [PATCH 1/4] chore: Bump Rust edition to 2024 Edition 2024 pairs with Cargo resolver 3, which was suggested as a way to keep dependency resolution aligned with the workspace MSRV. MSRV is already 1.88, so only the edition/resolver change is needed. Also wrap `std::env::set_var` call sites in `unsafe` (now required) and apply rustfmt's edition-2024 import sorting. Closes #971 Co-authored-by: Daniel Szoke --- CHANGELOG.md | 4 ++++ Cargo.toml | 4 ++-- sentry-actix/README.md | 4 +++- sentry-actix/examples/basic.rs | 6 ++++-- sentry-actix/src/lib.rs | 14 ++++++++------ sentry-anyhow/src/lib.rs | 11 ++++++++--- sentry-backtrace/src/lib.rs | 2 +- sentry-backtrace/src/utils.rs | 7 ++++++- sentry-contexts/build.rs | 2 +- sentry-contexts/src/integration.rs | 2 +- sentry-contexts/src/utils.rs | 7 ++++--- sentry-core/benches/scope_benchmark.rs | 2 +- sentry-core/src/client/batcher.rs | 2 +- sentry-core/src/client/client_reports/inner.rs | 2 +- sentry-core/src/client/client_reports/mod.rs | 2 +- sentry-core/src/client/envelope_sender.rs | 2 +- sentry-core/src/client/mod.rs | 4 ++-- sentry-core/src/error.rs | 2 +- sentry-core/src/futures.rs | 2 +- sentry-core/src/hub_impl.rs | 2 +- sentry-core/src/integration.rs | 4 ++-- sentry-core/src/performance.rs | 4 ++-- sentry-core/src/scope/noop.rs | 2 +- sentry-core/src/transport/options.rs | 2 +- sentry-core/tests/metrics.rs | 2 +- sentry-debug-images/src/images.rs | 2 +- sentry-opentelemetry/src/converters.rs | 2 +- sentry-opentelemetry/src/processor.rs | 4 ++-- sentry-opentelemetry/src/propagator.rs | 6 +++--- .../captures_transaction_with_nested_spans.rs | 3 +-- .../tests/creates_distributed_trace.rs | 3 +-- sentry-slog/src/converters.rs | 4 ++-- sentry-slog/src/lib.rs | 2 +- sentry-tower/src/http.rs | 4 ++-- sentry-tracing/src/converters.rs | 4 ++-- sentry-tracing/src/layer/mod.rs | 4 ++-- sentry-tracing/src/layer/span_guard_stack.rs | 2 +- .../tests/future_cross_thread_info_span.rs | 5 ++--- sentry-tracing/tests/transaction_assertions/mod.rs | 2 +- sentry-types/src/dsn.rs | 2 +- .../src/protocol/client_report/envelope_losses.rs | 2 +- sentry-types/src/protocol/envelope.rs | 2 +- sentry-types/src/protocol/v7.rs | 8 ++++---- sentry-types/src/utils.rs | 4 ++-- sentry-types/tests/test_auth.rs | 6 ++++-- sentry-types/tests/test_protocol_v7.rs | 2 +- sentry/src/defaults.rs | 8 ++++++-- sentry/src/init.rs | 2 +- sentry/src/lib.rs | 2 +- sentry/src/transports/curl.rs | 6 +++--- sentry/src/transports/embedded_svc_http.rs | 2 +- sentry/src/transports/ratelimit.rs | 2 +- sentry/src/transports/reqwest.rs | 8 ++++---- sentry/src/transports/thread.rs | 6 +++--- sentry/src/transports/tokio_thread.rs | 6 +++--- sentry/src/transports/ureq.rs | 6 +++--- sentry/tests/test_basic.rs | 4 ++-- sentry/tests/test_tower.rs | 2 +- 58 files changed, 124 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 513383656..c8e3625b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,10 @@ - Restored the reqwest transport's pre-0.13 protocol features by disabling HTTP/2 and native-TLS ALPN ([#1258](https://github.com/getsentry/sentry-rust/pull/1258)). +### Internal + +- Updated the Rust edition to 2024 ([#971](https://github.com/getsentry/sentry-rust/issues/971)). + ## 0.48.5 ### Fixes diff --git a/Cargo.toml b/Cargo.toml index 575a3b768..d65469962 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "2" +resolver = "3" members = [ "sentry", "sentry-actix", @@ -21,7 +21,7 @@ members = [ authors = ["Sentry "] repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" -edition = "2021" +edition = "2024" rust-version = "1.88" [workspace.lints.clippy] diff --git a/sentry-actix/README.md b/sentry-actix/README.md index 96713be73..dfa4b1358 100644 --- a/sentry-actix/README.md +++ b/sentry-actix/README.md @@ -29,7 +29,9 @@ fn main() -> io::Result<()> { let _guard = sentry::init( sentry::ClientOptions::new().maybe_release(sentry::release_name!()), ); - std::env::set_var("RUST_BACKTRACE", "1"); + unsafe { + std::env::set_var("RUST_BACKTRACE", "1"); + } let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() diff --git a/sentry-actix/examples/basic.rs b/sentry-actix/examples/basic.rs index 673a34ce4..f09a16c33 100644 --- a/sentry-actix/examples/basic.rs +++ b/sentry-actix/examples/basic.rs @@ -1,7 +1,7 @@ use std::env; use std::io; -use actix_web::{get, App, Error, HttpRequest, HttpServer}; +use actix_web::{App, Error, HttpRequest, HttpServer, get}; use sentry::Level; #[get("/")] @@ -30,7 +30,9 @@ fn main() -> io::Result<()> { .session_mode(sentry::SessionMode::Request) .debug(true), ); - env::set_var("RUST_BACKTRACE", "1"); + unsafe { + env::set_var("RUST_BACKTRACE", "1"); + } let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 7e2c7e94e..e8b472898 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -21,7 +21,9 @@ //! let _guard = sentry::init( //! sentry::ClientOptions::new().maybe_release(sentry::release_name!()), //! ); -//! std::env::set_var("RUST_BACKTRACE", "1"); +//! unsafe { +//! std::env::set_var("RUST_BACKTRACE", "1"); +//! } //! //! let runtime = tokio::runtime::Builder::new_multi_thread() //! .enable_all() @@ -79,16 +81,16 @@ use std::rc::Rc; use std::sync::Arc; use actix_http::header::{self, HeaderMap}; +use actix_web::Error; use actix_web::dev::{Service, ServiceRequest, ServiceResponse, Transform}; use actix_web::http::StatusCode; -use actix_web::Error; use bytes::{Bytes, BytesMut}; -use futures_util::future::{ok, Future, Ready}; +use futures_util::future::{Future, Ready, ok}; use futures_util::{FutureExt as _, TryStreamExt as _}; +use sentry_core::MaxRequestBodySize; use sentry_core::protocol::{self, ClientSdkPackage, Event, Request}; use sentry_core::utils::{is_sensitive_header, scrub_pii_from_url}; -use sentry_core::MaxRequestBodySize; use sentry_core::{Hub, SentryFutureExt}; /// A helper construct that can be used to reconfigure and build the middleware. @@ -476,8 +478,8 @@ mod tests { use std::io; use actix_web::body::BoxBody; - use actix_web::test::{call_service, init_service, TestRequest}; - use actix_web::{get, web, App, HttpRequest, HttpResponse}; + use actix_web::test::{TestRequest, call_service, init_service}; + use actix_web::{App, HttpRequest, HttpResponse, get, web}; use futures::executor::block_on; use futures::future::join_all; diff --git a/sentry-anyhow/src/lib.rs b/sentry-anyhow/src/lib.rs index d5cde23f8..adea9da28 100644 --- a/sentry-anyhow/src/lib.rs +++ b/sentry-anyhow/src/lib.rs @@ -41,9 +41,9 @@ #![warn(missing_docs)] #![deny(unsafe_code)] +use sentry_core::Hub; use sentry_core::protocol::Event; use sentry_core::types::Uuid; -use sentry_core::Hub; /// Captures an [`anyhow::Error`]. /// @@ -98,12 +98,15 @@ impl AnyhowHubExt for Hub { } #[cfg(all(feature = "backtrace", test))] +#[allow(unsafe_code)] mod tests { use super::*; #[test] fn test_event_from_error_with_backtrace() { - std::env::set_var("RUST_BACKTRACE", "1"); + unsafe { + std::env::set_var("RUST_BACKTRACE", "1"); + } let event = event_from_error(&anyhow::anyhow!("Oh jeez")); @@ -121,7 +124,9 @@ mod tests { #[test] fn test_capture_anyhow_uses_event_from_error_helper() { - std::env::set_var("RUST_BACKTRACE", "1"); + unsafe { + std::env::set_var("RUST_BACKTRACE", "1"); + } let err = &anyhow::anyhow!("Oh jeez"); diff --git a/sentry-backtrace/src/lib.rs b/sentry-backtrace/src/lib.rs index ee6c18503..f5f6484b4 100644 --- a/sentry-backtrace/src/lib.rs +++ b/sentry-backtrace/src/lib.rs @@ -14,7 +14,7 @@ mod trim; mod utils; pub use crate::integration::{ - current_thread, AttachStacktraceIntegration, ProcessStacktraceIntegration, + AttachStacktraceIntegration, ProcessStacktraceIntegration, current_thread, }; pub use crate::parse::parse_stacktrace; pub use crate::process::{backtrace_to_stacktrace, process_event_stacktrace}; diff --git a/sentry-backtrace/src/utils.rs b/sentry-backtrace/src/utils.rs index 1ce0750e0..a6fc1ecb7 100644 --- a/sentry-backtrace/src/utils.rs +++ b/sentry-backtrace/src/utils.rs @@ -228,7 +228,12 @@ mod tests { &strip_symbol(">::call_once"), ">::call_once" ); - assert_eq!(&strip_symbol(">, core[bb3d6b31f0e973c8]::cell::Cell)>>::with::<::with<::with_active::{closure#0}, ()>::{closure#0}, ()>::{closure#0}, ()>"), ">, core::cell::Cell)>>::with::<::with<::with_active::{closure#0}, ()>::{closure#0}, ()>::{closure#0}, ()>"); + assert_eq!( + &strip_symbol( + ">, core[bb3d6b31f0e973c8]::cell::Cell)>>::with::<::with<::with_active::{closure#0}, ()>::{closure#0}, ()>::{closure#0}, ()>" + ), + ">, core::cell::Cell)>>::with::<::with<::with_active::{closure#0}, ()>::{closure#0}, ()>::{closure#0}, ()>" + ); } #[test] diff --git a/sentry-contexts/build.rs b/sentry-contexts/build.rs index c42137376..e05beb7de 100644 --- a/sentry-contexts/build.rs +++ b/sentry-contexts/build.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::Write; use std::path::Path; -use rustc_version::{version, version_meta, Channel}; +use rustc_version::{Channel, version, version_meta}; fn main() -> Result<(), Box> { let out_dir = env::var("OUT_DIR")?; diff --git a/sentry-contexts/src/integration.rs b/sentry-contexts/src/integration.rs index d9b887288..9a515ae4b 100644 --- a/sentry-contexts/src/integration.rs +++ b/sentry-contexts/src/integration.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; -use sentry_core::protocol::map::Entry; use sentry_core::protocol::Event; +use sentry_core::protocol::map::Entry; use sentry_core::{ClientOptions, Integration}; use crate::utils::{device_context, os_context, rust_context, server_name}; diff --git a/sentry-contexts/src/utils.rs b/sentry-contexts/src/utils.rs index 6c311a36e..bd996d6f4 100644 --- a/sentry-contexts/src/utils.rs +++ b/sentry-contexts/src/utils.rs @@ -92,9 +92,10 @@ mod model_support { let dot_count = v.split('.').count() - 1; assert_eq!(dot_count, 2); let b = get_macos_build().unwrap(); - assert!(b - .chars() - .all(|c| c.is_ascii_alphabetic() || c.is_ascii_digit())); + assert!( + b.chars() + .all(|c| c.is_ascii_alphabetic() || c.is_ascii_digit()) + ); } } diff --git a/sentry-core/benches/scope_benchmark.rs b/sentry-core/benches/scope_benchmark.rs index defa83666..f3ed595ce 100644 --- a/sentry-core/benches/scope_benchmark.rs +++ b/sentry-core/benches/scope_benchmark.rs @@ -25,7 +25,7 @@ use std::ops::Range; #[cfg(feature = "client")] use std::sync::Arc; -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, criterion_group, criterion_main}; use sentry::protocol::Breadcrumb; #[cfg(not(feature = "client"))] use sentry_core as sentry; diff --git a/sentry-core/src/client/batcher.rs b/sentry-core/src/client/batcher.rs index 73132c33a..d3bed6746 100644 --- a/sentry-core/src/client/batcher.rs +++ b/sentry-core/src/client/batcher.rs @@ -7,8 +7,8 @@ use std::thread::JoinHandle; use std::time::{Duration, Instant}; use super::EnvelopeSender; -use crate::protocol::EnvelopeItem; use crate::Envelope; +use crate::protocol::EnvelopeItem; use sentry_types::protocol::v7::Log; #[cfg(feature = "metrics")] use sentry_types::protocol::v7::Metric; diff --git a/sentry-core/src/client/client_reports/inner.rs b/sentry-core/src/client/client_reports/inner.rs index f47660205..799d16786 100644 --- a/sentry-core/src/client/client_reports/inner.rs +++ b/sentry-core/src/client/client_reports/inner.rs @@ -6,8 +6,8 @@ use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -use sentry_types::protocol::v7::client_report::{Category, Item, Reason, Report}; use sentry_types::IndexedEnum; +use sentry_types::protocol::v7::client_report::{Category, Item, Reason, Report}; const ARRAY_SIZE: usize = Reason::VARIANTS.len() * Category::VARIANTS.len(); diff --git a/sentry-core/src/client/client_reports/mod.rs b/sentry-core/src/client/client_reports/mod.rs index cf40bbe07..afd729e00 100644 --- a/sentry-core/src/client/client_reports/mod.rs +++ b/sentry-core/src/client/client_reports/mod.rs @@ -8,10 +8,10 @@ #[cfg(all(target_has_atomic = "64", target_has_atomic = "8"))] use std::sync::Arc; +use sentry_types::protocol::v7::ClientReport; #[cfg(all(target_has_atomic = "64", target_has_atomic = "8"))] use sentry_types::protocol::v7::client_report::ItemLoss; use sentry_types::protocol::v7::client_report::{Category, LossSource, Reason}; -use sentry_types::protocol::v7::ClientReport; #[cfg(all(target_has_atomic = "64", target_has_atomic = "8"))] use self::inner::ClientReportAggregatorInner; diff --git a/sentry-core/src/client/envelope_sender.rs b/sentry-core/src/client/envelope_sender.rs index a84296e45..f765d15f7 100644 --- a/sentry-core/src/client/envelope_sender.rs +++ b/sentry-core/src/client/envelope_sender.rs @@ -7,10 +7,10 @@ use std::sync::Arc; use std::time::Duration; +use sentry_types::protocol::v7::EnvelopeItem; use sentry_types::protocol::v7::client_report::{ Category as ClientReportCategory, LossSource, Reason as ClientReportReason, }; -use sentry_types::protocol::v7::EnvelopeItem; use self::slot::TransportSlot; use super::client_reports::{ClientReportAggregator, Recorder}; diff --git a/sentry-core/src/client/mod.rs b/sentry-core/src/client/mod.rs index 77abec836..307995115 100644 --- a/sentry-core/src/client/mod.rs +++ b/sentry-core/src/client/mod.rs @@ -22,13 +22,13 @@ use sentry_types::random_uuid; #[cfg(any(feature = "logs", feature = "metrics"))] use self::batcher::Batcher; +#[cfg(feature = "release-health")] +use crate::SessionMode; use crate::constants::SDK_INFO; use crate::protocol::{ClientSdkInfo, Event}; #[cfg(feature = "release-health")] use crate::session::SessionFlusher; use crate::types::{Dsn, Uuid}; -#[cfg(feature = "release-health")] -use crate::SessionMode; use crate::{ClientOptions, Envelope, EventSamplingStrategy, Hub, Integration, Scope}; #[cfg(feature = "logs")] diff --git a/sentry-core/src/error.rs b/sentry-core/src/error.rs index 0540c569b..d08cbcd12 100644 --- a/sentry-core/src/error.rs +++ b/sentry-core/src/error.rs @@ -1,8 +1,8 @@ use std::error::Error; +use crate::Hub; use crate::protocol::{Event, Exception, Level}; use crate::types::Uuid; -use crate::Hub; impl Hub { /// Capture any `std::error::Error`. diff --git a/sentry-core/src/futures.rs b/sentry-core/src/futures.rs index 5d8e7f05e..f169528d1 100644 --- a/sentry-core/src/futures.rs +++ b/sentry-core/src/futures.rs @@ -69,7 +69,7 @@ impl SentryFutureExt for F where F: Future {} #[cfg(all(test, feature = "test"))] mod tests { use crate::test::with_captured_events; - use crate::{capture_message, configure_scope, Hub, Level, SentryFutureExt}; + use crate::{Hub, Level, SentryFutureExt, capture_message, configure_scope}; use tokio::runtime::Runtime; #[test] diff --git a/sentry-core/src/hub_impl.rs b/sentry-core/src/hub_impl.rs index e08b009e2..bfb79be26 100644 --- a/sentry-core/src/hub_impl.rs +++ b/sentry-core/src/hub_impl.rs @@ -5,7 +5,7 @@ use std::thread; use std::thread::ThreadId; use crate::Scope; -use crate::{scope::Stack, Client, Hub}; +use crate::{Client, Hub, scope::Stack}; static PROCESS_HUB: LazyLock = LazyLock::new(|| ProcessHub { hub: Arc::new(Hub::new(None, Arc::new(Default::default()))), diff --git a/sentry-core/src/integration.rs b/sentry-core/src/integration.rs index 3111f015d..0d2cb0af9 100644 --- a/sentry-core/src/integration.rs +++ b/sentry-core/src/integration.rs @@ -1,7 +1,7 @@ -use std::any::{type_name, Any}; +use std::any::{Any, type_name}; -use crate::protocol::Event; use crate::ClientOptions; +use crate::protocol::Event; /// Integration abstraction. /// diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index ae6056e0c..10a60cc3e 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -4,13 +4,13 @@ use std::ops::{Deref, DerefMut}; use std::sync::{Arc, Mutex, MutexGuard}; use std::time::SystemTime; +use sentry_types::protocol::v7::SpanId; #[cfg(feature = "client")] use sentry_types::protocol::v7::client_report::Reason as ClientReportReason; -use sentry_types::protocol::v7::SpanId; #[cfg(feature = "client")] use crate::clientoptions::TracesSamplingStrategy; -use crate::{protocol, Hub}; +use crate::{Hub, protocol}; #[cfg(feature = "client")] use crate::Client; diff --git a/sentry-core/src/scope/noop.rs b/sentry-core/src/scope/noop.rs index 13df41f4a..42e5f8bf3 100644 --- a/sentry-core/src/scope/noop.rs +++ b/sentry-core/src/scope/noop.rs @@ -1,10 +1,10 @@ use std::fmt; use std::panic::RefUnwindSafe; +use crate::TransactionOrSpan; #[cfg(feature = "logs")] use crate::protocol::Log; use crate::protocol::{Context, Event, Level, User, Value}; -use crate::TransactionOrSpan; /// A minimal API scope guard. /// diff --git a/sentry-core/src/transport/options.rs b/sentry-core/src/transport/options.rs index f6f2b51b8..e59ef1e84 100644 --- a/sentry-core/src/transport/options.rs +++ b/sentry-core/src/transport/options.rs @@ -4,9 +4,9 @@ use std::borrow::Cow; use sentry_types::Dsn; +use crate::ClientOptions; #[cfg(feature = "client")] use crate::client_report::Recorder as ClientReportRecorder; -use crate::ClientOptions; /// Options for a transport. #[derive(Debug)] diff --git a/sentry-core/tests/metrics.rs b/sentry-core/tests/metrics.rs index 656791215..27fbe0484 100644 --- a/sentry-core/tests/metrics.rs +++ b/sentry-core/tests/metrics.rs @@ -6,8 +6,8 @@ use anyhow::{Context, Result}; use sentry::protocol::{MetricType, Unit, Value}; use sentry_core::protocol::{EnvelopeItem, ItemContainer}; -use sentry_core::{metrics, test}; use sentry_core::{ClientOptions, TransactionContext}; +use sentry_core::{metrics, test}; use sentry_types::protocol::v7::{Envelope, LogAttribute, Metric, User}; /// Test that metrics are sent when metrics are enabled. diff --git a/sentry-debug-images/src/images.rs b/sentry-debug-images/src/images.rs index 71fbcae32..8ccb7c8aa 100644 --- a/sentry-debug-images/src/images.rs +++ b/sentry-debug-images/src/images.rs @@ -3,7 +3,7 @@ use std::env; use sentry_core::protocol::{DebugImage, SymbolicDebugImage}; use sentry_core::types::{CodeId, DebugId, Uuid}; -use findshlibs::{SharedLibrary, SharedLibraryId, TargetSharedLibrary, TARGET_SUPPORTED}; +use findshlibs::{SharedLibrary, SharedLibraryId, TARGET_SUPPORTED, TargetSharedLibrary}; const UUID_SIZE: usize = 16; diff --git a/sentry-opentelemetry/src/converters.rs b/sentry-opentelemetry/src/converters.rs index b0c8c326e..17fae7ec7 100644 --- a/sentry-opentelemetry/src/converters.rs +++ b/sentry-opentelemetry/src/converters.rs @@ -1,4 +1,4 @@ -use sentry_core::protocol::{value::Number, SpanId, SpanStatus, TraceId, Value}; +use sentry_core::protocol::{SpanId, SpanStatus, TraceId, Value, value::Number}; pub(crate) fn convert_span_id(span_id: &opentelemetry::SpanId) -> SpanId { span_id.to_bytes().into() diff --git a/sentry-opentelemetry/src/processor.rs b/sentry-opentelemetry/src/processor.rs index a51edebe1..fa85137cd 100644 --- a/sentry-opentelemetry/src/processor.rs +++ b/sentry-opentelemetry/src/processor.rs @@ -12,9 +12,9 @@ use std::collections::HashMap; use std::sync::{Arc, LazyLock, Mutex}; use std::time::{Duration, SystemTime}; -use opentelemetry::global::ObjectSafeSpan; -use opentelemetry::trace::{get_active_span, SpanId}; use opentelemetry::Context; +use opentelemetry::global::ObjectSafeSpan; +use opentelemetry::trace::{SpanId, get_active_span}; use opentelemetry_sdk::error::OTelSdkResult; use opentelemetry_sdk::trace::{Span, SpanData, SpanProcessor}; diff --git a/sentry-opentelemetry/src/propagator.rs b/sentry-opentelemetry/src/propagator.rs index 396f95f7b..ac99101ed 100644 --- a/sentry-opentelemetry/src/propagator.rs +++ b/sentry-opentelemetry/src/propagator.rs @@ -15,12 +15,12 @@ use std::sync::LazyLock; use opentelemetry::{ - propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, - trace::TraceContextExt, Context, SpanId, TraceId, + propagation::{Extractor, Injector, TextMapPropagator, text_map_propagator::FieldIter}, + trace::TraceContextExt, }; -use sentry_core::parse_headers; use sentry_core::SentryTrace; +use sentry_core::parse_headers; use crate::converters::{convert_span_id, convert_trace_id}; diff --git a/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs b/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs index 551cd3a0a..86f0c4174 100644 --- a/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs +++ b/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs @@ -1,9 +1,8 @@ mod shared; use opentelemetry::{ - global, + KeyValue, global, trace::{Status, TraceContextExt, Tracer, TracerProvider}, - KeyValue, }; use opentelemetry_sdk::trace::SdkTracerProvider; use sentry_opentelemetry::{SentryPropagator, SentrySpanProcessor}; diff --git a/sentry-opentelemetry/tests/creates_distributed_trace.rs b/sentry-opentelemetry/tests/creates_distributed_trace.rs index f0dbf3a0f..81208f0fe 100644 --- a/sentry-opentelemetry/tests/creates_distributed_trace.rs +++ b/sentry-opentelemetry/tests/creates_distributed_trace.rs @@ -1,10 +1,9 @@ mod shared; use opentelemetry::{ - global, + Context, global, propagation::TextMapPropagator, trace::{TraceContextExt, Tracer, TracerProvider}, - Context, }; use opentelemetry_sdk::trace::SdkTracerProvider; use sentry_opentelemetry::{SentryPropagator, SentrySpanProcessor}; diff --git a/sentry-slog/src/converters.rs b/sentry-slog/src/converters.rs index 3dcfbf365..e7e432d4d 100644 --- a/sentry-slog/src/converters.rs +++ b/sentry-slog/src/converters.rs @@ -1,5 +1,5 @@ use sentry_core::protocol::{Breadcrumb, Event, Level, Map, Value}; -use slog::{Key, OwnedKVList, Record, Serializer, KV}; +use slog::{KV, Key, OwnedKVList, Record, Serializer}; use std::fmt; /// Converts a [`slog::Level`] to a Sentry [`Level`] @@ -106,7 +106,7 @@ mod test { use super::*; use serde::Serialize; - use slog::{b, o, record, Level}; + use slog::{Level, b, o, record}; #[derive(Serialize, Clone)] struct Something { diff --git a/sentry-slog/src/lib.rs b/sentry-slog/src/lib.rs index 60e7cbcc2..3b805895f 100644 --- a/sentry-slog/src/lib.rs +++ b/sentry-slog/src/lib.rs @@ -79,4 +79,4 @@ mod converters; mod drain; pub use converters::*; -pub use drain::{default_filter, LevelFilter, RecordMapping, SentryDrain}; +pub use drain::{LevelFilter, RecordMapping, SentryDrain, default_filter}; diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index 5b7c2f4eb..6e9c7d898 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -3,10 +3,10 @@ use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; -use http::{header, uri, Request, Response, StatusCode}; +use http::{Request, Response, StatusCode, header, uri}; use pin_project::pinned_drop; use sentry_core::utils::{is_sensitive_header, scrub_pii_from_url}; -use sentry_core::{protocol, Hub}; +use sentry_core::{Hub, protocol}; use tower_layer::Layer; use tower_service::Service; diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 9ae410946..7fc1cd323 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -4,11 +4,11 @@ use std::error::Error; use sentry_core::protocol::{Event, Exception, Mechanism, Value}; #[cfg(feature = "logs")] use sentry_core::protocol::{Log, LogAttribute, LogLevel}; -use sentry_core::{event_from_error, Breadcrumb, Level, TransactionOrSpan}; +use sentry_core::{Breadcrumb, Level, TransactionOrSpan, event_from_error}; #[cfg(feature = "logs")] use std::time::SystemTime; -use tracing_core::field::{Field, Visit}; use tracing_core::Subscriber; +use tracing_core::field::{Field, Visit}; use tracing_subscriber::layer::Context; use tracing_subscriber::registry::LookupSpan; diff --git a/sentry-tracing/src/layer/mod.rs b/sentry-tracing/src/layer/mod.rs index fba1a4e0a..e10105585 100644 --- a/sentry-tracing/src/layer/mod.rs +++ b/sentry-tracing/src/layer/mod.rs @@ -7,15 +7,15 @@ use bitflags::bitflags; use sentry_core::protocol::Value; use sentry_core::{Breadcrumb, Hub, HubSwitchGuard, TransactionOrSpan}; use tracing_core::field::Visit; -use tracing_core::{span, Event, Field, Level, Metadata, Subscriber}; +use tracing_core::{Event, Field, Level, Metadata, Subscriber, span}; use tracing_subscriber::layer::{Context, Layer}; use tracing_subscriber::registry::LookupSpan; -use crate::converters::*; use crate::SENTRY_NAME_FIELD; use crate::SENTRY_OP_FIELD; use crate::SENTRY_TRACE_FIELD; use crate::TAGS_PREFIX; +use crate::converters::*; use span_guard_stack::SpanGuardStack; mod span_guard_stack; diff --git a/sentry-tracing/src/layer/span_guard_stack.rs b/sentry-tracing/src/layer/span_guard_stack.rs index 753454a27..2e96ea6fa 100644 --- a/sentry-tracing/src/layer/span_guard_stack.rs +++ b/sentry-tracing/src/layer/span_guard_stack.rs @@ -1,8 +1,8 @@ //! This module contains code for stack-like storage for `HubSwitchGuard`s keyed //! by tracing span ID. -use std::collections::hash_map::Entry; use std::collections::HashMap; +use std::collections::hash_map::Entry; use sentry_core::HubSwitchGuard; use tracing_core::span::Id as SpanId; diff --git a/sentry-tracing/tests/future_cross_thread_info_span.rs b/sentry-tracing/tests/future_cross_thread_info_span.rs index bc9198a34..8bd9262b8 100644 --- a/sentry-tracing/tests/future_cross_thread_info_span.rs +++ b/sentry-tracing/tests/future_cross_thread_info_span.rs @@ -32,9 +32,8 @@ fn future_cross_thread_info_span() { .expect("expected thread2 to panic with a String message"); assert!( - thread2_panic_message.starts_with( - "[SentryLayer] missing HubSwitchGuard on exit for span" - ), + thread2_panic_message + .starts_with("[SentryLayer] missing HubSwitchGuard on exit for span"), "Thread 2 panicked, but not for the expected reason. It is also possible that the panic \ message was changed without updating this test." ); diff --git a/sentry-tracing/tests/transaction_assertions/mod.rs b/sentry-tracing/tests/transaction_assertions/mod.rs index 91595aece..5bfa646fa 100644 --- a/sentry-tracing/tests/transaction_assertions/mod.rs +++ b/sentry-tracing/tests/transaction_assertions/mod.rs @@ -1,5 +1,5 @@ -use sentry::protocol::{EnvelopeItem, Transaction}; use sentry::Envelope; +use sentry::protocol::{EnvelopeItem, Transaction}; /// Assert that the given envelopes contain exactly one `Envelope`, containing /// exactly one `EnvelopeItem`, which is a `Transaction` with the given name. diff --git a/sentry-types/src/dsn.rs b/sentry-types/src/dsn.rs index 4f203e4d5..51a799579 100644 --- a/sentry-types/src/dsn.rs +++ b/sentry-types/src/dsn.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use thiserror::Error; use url::Url; -use crate::auth::{auth_from_dsn_and_client, Auth}; +use crate::auth::{Auth, auth_from_dsn_and_client}; use crate::project_id::{ParseProjectIdError, ProjectId}; /// Represents a dsn url parsing error. diff --git a/sentry-types/src/protocol/client_report/envelope_losses.rs b/sentry-types/src/protocol/client_report/envelope_losses.rs index 0db2482df..f15554544 100644 --- a/sentry-types/src/protocol/client_report/envelope_losses.rs +++ b/sentry-types/src/protocol/client_report/envelope_losses.rs @@ -8,7 +8,7 @@ use crate::protocol::v7::{ }; use super::list::Iter as ClientReportItemIter; -use super::{relay_size, Category, Item as ClientReportItem, Reason}; +use super::{Category, Item as ClientReportItem, Reason, relay_size}; /// A trait for protocol types which can be a source of lost Sentry data if discarded. pub trait LossSource: private::Sealed { diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index e76ce3549..d48111920 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -900,8 +900,8 @@ mod test { use protocol::Map; use serde_json::Value; - use time::format_description::well_known::Rfc3339; use time::OffsetDateTime; + use time::format_description::well_known::Rfc3339; use uuid::Uuid; use super::*; diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index f05394258..be0cb656e 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -16,7 +16,7 @@ use std::str; use std::time::SystemTime; use self::debugid::{CodeId, DebugId}; -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use thiserror::Error; pub use url::Url; @@ -40,7 +40,7 @@ pub mod client_report { /// An arbitrary (JSON) value. pub mod value { - pub use serde_json::value::{from_value, to_value, Index, Map, Number, Value}; + pub use serde_json::value::{Index, Map, Number, Value, from_value, to_value}; } /// The internally used arbitrary data map type. @@ -2364,8 +2364,8 @@ impl<'de> Deserialize<'de> for LogAttribute { } _ => { return Err(de::Error::custom(format!( - "expected type to be 'string' | 'integer' | 'double' | 'boolean', found {type_str}" - ))) + "expected type to be 'string' | 'integer' | 'double' | 'boolean', found {type_str}" + ))); } } diff --git a/sentry-types/src/utils.rs b/sentry-types/src/utils.rs index 83d7a6581..db3fe7708 100644 --- a/sentry-types/src/utils.rs +++ b/sentry-types/src/utils.rs @@ -1,8 +1,8 @@ use std::convert::{TryFrom, TryInto}; use std::time::{Duration, SystemTime}; -use time::format_description::well_known::Rfc3339; use time::OffsetDateTime; +use time::format_description::well_known::Rfc3339; /// Converts a `SystemTime` object into a float timestamp. pub fn datetime_to_timestamp(st: &SystemTime) -> f64 { @@ -218,7 +218,7 @@ pub mod ts_rfc3339_opt { /// assert_eq!(deserialized, config); /// ``` pub(crate) mod display_from_str_opt { - use serde::{de, ser, Deserialize}; + use serde::{Deserialize, de, ser}; pub fn serialize(value: &Option, serializer: S) -> Result where diff --git a/sentry-types/tests/test_auth.rs b/sentry-types/tests/test_auth.rs index f7b54cf7b..718f06c56 100644 --- a/sentry-types/tests/test_auth.rs +++ b/sentry-types/tests/test_auth.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::time::{Duration, SystemTime}; -use sentry_types::{protocol, Auth, Dsn}; +use sentry_types::{Auth, Dsn, protocol}; #[test] fn test_auth_parsing() { @@ -92,7 +92,9 @@ fn test_auth_to_json() { let auth = Auth::from_pairs(cont).unwrap(); assert_eq!( - serde_json::to_string(&auth).expect("could not serialize").as_str(), + serde_json::to_string(&auth) + .expect("could not serialize") + .as_str(), "{\"sentry_client\":\"raven-js/3.23.3\",\"sentry_version\":7,\"sentry_key\":\"4bb5d94de752a36b8b87851a3f82726a\",\"sentry_secret\":null}" ); } diff --git a/sentry-types/tests/test_protocol_v7.rs b/sentry-types/tests/test_protocol_v7.rs index 841cf19d1..8db0a0850 100644 --- a/sentry-types/tests/test_protocol_v7.rs +++ b/sentry-types/tests/test_protocol_v7.rs @@ -1563,7 +1563,7 @@ fn test_orientation() { mod test_logs { use sentry_types::protocol::v7::LogAttribute; - use serde_json::{json, Value}; + use serde_json::{Value, json}; #[test] fn test_log_attribute_serialization() { diff --git a/sentry/src/defaults.rs b/sentry/src/defaults.rs index c29bcab07..538a0ee3c 100644 --- a/sentry/src/defaults.rs +++ b/sentry/src/defaults.rs @@ -28,7 +28,9 @@ use crate::{ClientOptions, Integration}; /// /// # Examples /// ``` -/// std::env::set_var("SENTRY_RELEASE", "release-from-env"); +/// unsafe { +/// std::env::set_var("SENTRY_RELEASE", "release-from-env"); +/// } /// /// let options = sentry::ClientOptions::default(); /// assert_eq!(options.release, None); @@ -129,7 +131,9 @@ mod tests { // I doubt anyone runs test code without debug assertions assert_eq!(opts.environment.unwrap(), "development"); - env::set_var("SENTRY_ENVIRONMENT", "env-from-env"); + unsafe { + env::set_var("SENTRY_ENVIRONMENT", "env-from-env"); + } let opts = apply_defaults(Default::default()); assert_eq!(opts.environment.unwrap(), "env-from-env"); } diff --git a/sentry/src/init.rs b/sentry/src/init.rs index 29ccaffab..e792b6625 100644 --- a/sentry/src/init.rs +++ b/sentry/src/init.rs @@ -1,8 +1,8 @@ use std::sync::Arc; -use sentry_core::sentry_debug; #[cfg(feature = "release-health")] use sentry_core::SessionMode; +use sentry_core::sentry_debug; use crate::defaults::apply_defaults; use crate::{Client, ClientOptions, Hub}; diff --git a/sentry/src/lib.rs b/sentry/src/lib.rs index d67f27ce5..b40560fa7 100644 --- a/sentry/src/lib.rs +++ b/sentry/src/lib.rs @@ -144,7 +144,7 @@ pub use sentry_core::*; // added public API pub use crate::defaults::apply_defaults; -pub use crate::init::{init, ClientInitGuard}; +pub use crate::init::{ClientInitGuard, init}; /// Available Sentry Integrations. /// diff --git a/sentry/src/transports/curl.rs b/sentry/src/transports/curl.rs index 871eff584..f61b68b5b 100644 --- a/sentry/src/transports/curl.rs +++ b/sentry/src/transports/curl.rs @@ -2,15 +2,15 @@ use std::io::{Cursor, Read}; use std::time::Duration; use curl::easy::Easy as CurlClient; -use sentry_core::client_report::Reason as LossReason; use sentry_core::TransportOptions; +use sentry_core::client_report::Reason as LossReason; use super::{ + HTTP_PAYLOAD_TOO_LARGE, HTTP_PAYLOAD_TOO_LARGE_MESSAGE, RateLimiter, thread::{TransportThread, TransportThreadOptions}, - RateLimiter, HTTP_PAYLOAD_TOO_LARGE, HTTP_PAYLOAD_TOO_LARGE_MESSAGE, }; -use crate::{sentry_debug, types::Scheme, ClientOptions, Envelope, Transport}; +use crate::{ClientOptions, Envelope, Transport, sentry_debug, types::Scheme}; /// The status code returned for rate-limited envelopes. const HTTP_RATE_LIMIT_STATUS: u32 = 429; diff --git a/sentry/src/transports/embedded_svc_http.rs b/sentry/src/transports/embedded_svc_http.rs index 72af2e825..89a6cbb1c 100644 --- a/sentry/src/transports/embedded_svc_http.rs +++ b/sentry/src/transports/embedded_svc_http.rs @@ -1,7 +1,7 @@ use sentry_core::TransportOptions; use super::{HTTP_PAYLOAD_TOO_LARGE, HTTP_PAYLOAD_TOO_LARGE_MESSAGE}; -use crate::{sentry_debug, ClientOptions, Transport}; +use crate::{ClientOptions, Transport, sentry_debug}; use embedded_svc::http::client::Client as HttpClient; use esp_idf_svc::{http::client::EspHttpConnection, io::Write}; diff --git a/sentry/src/transports/ratelimit.rs b/sentry/src/transports/ratelimit.rs index 3865fcbe2..f1a1c5b98 100644 --- a/sentry/src/transports/ratelimit.rs +++ b/sentry/src/transports/ratelimit.rs @@ -3,9 +3,9 @@ use sentry_core::client_report::{Reason as ClientReportReason, Recorder as Clien use sentry_core::protocol::EnvelopeFilterCallbacks; use std::time::{Duration, SystemTime}; +use crate::Envelope; use crate::protocol::EnvelopeItem; use crate::protocol::ItemContainer; -use crate::Envelope; /// A Utility that helps with rate limiting sentry requests. #[derive(Debug, Default)] diff --git a/sentry/src/transports/reqwest.rs b/sentry/src/transports/reqwest.rs index 175904361..be1e2fc52 100644 --- a/sentry/src/transports/reqwest.rs +++ b/sentry/src/transports/reqwest.rs @@ -1,15 +1,15 @@ use std::time::Duration; -use reqwest::{header as ReqwestHeaders, Client as ReqwestClient, Proxy, StatusCode}; -use sentry_core::client_report::Reason as LossReason; +use reqwest::{Client as ReqwestClient, Proxy, StatusCode, header as ReqwestHeaders}; use sentry_core::TransportOptions; +use sentry_core::client_report::Reason as LossReason; use super::{ + HTTP_PAYLOAD_TOO_LARGE, HTTP_PAYLOAD_TOO_LARGE_MESSAGE, RateLimiter, tokio_thread::{TransportThread, TransportThreadOptions}, - RateLimiter, HTTP_PAYLOAD_TOO_LARGE, HTTP_PAYLOAD_TOO_LARGE_MESSAGE, }; -use crate::{sentry_debug, ClientOptions, Envelope, Transport}; +use crate::{ClientOptions, Envelope, Transport, sentry_debug}; /// The status code returned for rate-limited envelopes. const HTTP_RATE_LIMIT_STATUS: u16 = 429; diff --git a/sentry/src/transports/thread.rs b/sentry/src/transports/thread.rs index c08dac483..1a90eead0 100644 --- a/sentry/src/transports/thread.rs +++ b/sentry/src/transports/thread.rs @@ -1,6 +1,6 @@ -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::mpsc::{sync_channel, SyncSender, TrySendError}; use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::mpsc::{SyncSender, TrySendError, sync_channel}; use std::thread::{self, JoinHandle}; use std::time::Duration; @@ -9,7 +9,7 @@ use sentry_core::client_report::{Reason as ClientReportReason, Recorder as Clien use super::ratelimit::{RateLimiter, RateLimitingCategory}; #[cfg(doc)] use super::{StdTransportThread, StdTransportThreadOptions}; // so we can use pub re-exports in docs -use crate::{sentry_debug, Envelope}; +use crate::{Envelope, sentry_debug}; #[expect( clippy::large_enum_variant, diff --git a/sentry/src/transports/tokio_thread.rs b/sentry/src/transports/tokio_thread.rs index 69cd22a12..130a79b8f 100644 --- a/sentry/src/transports/tokio_thread.rs +++ b/sentry/src/transports/tokio_thread.rs @@ -1,6 +1,6 @@ -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::mpsc::{sync_channel, SyncSender, TrySendError}; use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::mpsc::{SyncSender, TrySendError, sync_channel}; use std::thread::{self, JoinHandle}; use std::time::Duration; @@ -9,7 +9,7 @@ use sentry_core::client_report::{Reason as ClientReportReason, Recorder as Clien use super::ratelimit::{RateLimiter, RateLimitingCategory}; #[cfg(doc)] use super::{TokioTransportThread, TokioTransportThreadOptions}; // so we can use pub re-exports in docs -use crate::{sentry_debug, Envelope}; +use crate::{Envelope, sentry_debug}; #[expect( clippy::large_enum_variant, diff --git a/sentry/src/transports/ureq.rs b/sentry/src/transports/ureq.rs index 521281d04..4e92e7f17 100644 --- a/sentry/src/transports/ureq.rs +++ b/sentry/src/transports/ureq.rs @@ -1,7 +1,7 @@ use std::time::Duration; -use sentry_core::client_report::Reason as LossReason; use sentry_core::TransportOptions; +use sentry_core::client_report::Reason as LossReason; use ureq::http::Response; #[cfg(any( feature = "rustls", @@ -12,11 +12,11 @@ use ureq::tls::{TlsConfig, TlsProvider}; use ureq::{Agent, Proxy}; use super::{ + HTTP_PAYLOAD_TOO_LARGE, HTTP_PAYLOAD_TOO_LARGE_MESSAGE, RateLimiter, thread::{TransportThread, TransportThreadOptions}, - RateLimiter, HTTP_PAYLOAD_TOO_LARGE, HTTP_PAYLOAD_TOO_LARGE_MESSAGE, }; -use crate::{sentry_debug, types::Scheme, ClientOptions, Envelope, Transport}; +use crate::{ClientOptions, Envelope, Transport, sentry_debug, types::Scheme}; /// The status code returned for rate-limited envelopes. const HTTP_RATE_LIMIT_STATUS: u16 = 429; diff --git a/sentry/tests/test_basic.rs b/sentry/tests/test_basic.rs index eb1222d5e..735f4420d 100644 --- a/sentry/tests/test_basic.rs +++ b/sentry/tests/test_basic.rs @@ -1,7 +1,7 @@ #![cfg(feature = "test")] -use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicUsize, Ordering}; use sentry::protocol::{ Attachment, Context, DynamicSamplingContext, EnvelopeHeaders, EnvelopeItem, @@ -267,7 +267,7 @@ fn test_panic_scope_pop() { fn test_basic_capture_log() { use std::time::SystemTime; - use sentry::{protocol::Log, protocol::LogAttribute, protocol::Map, Hub}; + use sentry::{Hub, protocol::Log, protocol::LogAttribute, protocol::Map}; let options = sentry::ClientOptions::new().enable_logs(true); let envelopes = sentry::test::with_captured_envelopes_options( diff --git a/sentry/tests/test_tower.rs b/sentry/tests/test_tower.rs index 4023e2cd3..a01886cd7 100644 --- a/sentry/tests/test_tower.rs +++ b/sentry/tests/test_tower.rs @@ -3,9 +3,9 @@ use std::sync::Arc; use sentry::{ + ClientOptions, Hub, protocol::{Breadcrumb, Level}, test::TestTransport, - ClientOptions, Hub, }; use sentry_tower::SentryLayer; use tower::{ServiceBuilder, ServiceExt}; From 8f0db30bf48887757e2185a215049171b9d7ad33 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 24 Jul 2026 15:36:17 +0000 Subject: [PATCH 2/4] meta: Link edition bump changelog entry to PR Closes [#971](https://github.com/getsentry/sentry-rust/issues/971) Closes [RUST-137](https://linear.app/getsentry/issue/RUST-137/bump-rust-edition-to-2024) Co-authored-by: Daniel Szoke --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e3625b0..89f392721 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ ### Internal -- Updated the Rust edition to 2024 ([#971](https://github.com/getsentry/sentry-rust/issues/971)). +- Updated the Rust edition to 2024 ([#1265](https://github.com/getsentry/sentry-rust/pull/1265)). ## 0.48.5 From 48daae576c98736028cc0290c917380bdd5d670e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 24 Jul 2026 15:38:51 +0000 Subject: [PATCH 3/4] ref: Collapse nested ifs into edition 2024 let chains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stable clippy (1.97) treats nested `if`/`if let` as `collapsible_if` and suggests `if … && let` chains, which edition 2024 enables. Related to [#971](https://github.com/getsentry/sentry-rust/issues/971) Related to [RUST-137](https://linear.app/getsentry/issue/RUST-137/bump-rust-edition-to-2024) Co-authored-by: Daniel Szoke --- sentry-actix/src/lib.rs | 27 ++++---- sentry-contexts/src/integration.rs | 11 ++-- sentry-core/src/client/mod.rs | 17 +++-- sentry-core/src/hub.rs | 5 +- sentry-core/src/performance.rs | 37 +++++------ sentry-core/src/scope/real.rs | 89 +++++++++++++-------------- sentry-core/src/session.rs | 10 +-- sentry-tracing/src/converters.rs | 38 ++++++------ sentry-types/src/protocol/envelope.rs | 28 ++++----- 9 files changed, 127 insertions(+), 135 deletions(-) diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index e8b472898..7ac145744 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -371,16 +371,17 @@ where }; // Response errors - if inner.capture_server_errors && res.response().status().is_server_error() { - if let Some(e) = res.response().error() { - let event_id = hub.capture_error(e); - - if inner.emit_header { - res.response_mut().headers_mut().insert( - "x-sentry-event".parse().unwrap(), - event_id.simple().to_string().parse().unwrap(), - ); - } + if inner.capture_server_errors + && res.response().status().is_server_error() + && let Some(e) = res.response().error() + { + let event_id = hub.capture_error(e); + + if inner.emit_header { + res.response_mut().headers_mut().insert( + "x-sentry-event".parse().unwrap(), + event_id.simple().to_string().parse().unwrap(), + ); } } @@ -445,10 +446,8 @@ fn sentry_request_from_http(request: &ServiceRequest, with_pii: bool) -> Request }; // If PII is enabled, include the remote address - if with_pii { - if let Some(remote) = request.connection_info().remote_addr() { - sentry_req.env.insert("REMOTE_ADDR".into(), remote.into()); - } + if with_pii && let Some(remote) = request.connection_info().remote_addr() { + sentry_req.env.insert("REMOTE_ADDR".into(), remote.into()); }; sentry_req diff --git a/sentry-contexts/src/integration.rs b/sentry-contexts/src/integration.rs index 9a515ae4b..48975257b 100644 --- a/sentry-contexts/src/integration.rs +++ b/sentry-contexts/src/integration.rs @@ -82,12 +82,11 @@ impl Integration for ContextIntegration { mut event: Event<'static>, _cfg: &ClientOptions, ) -> Option> { - if self.add_os { - if let Entry::Vacant(entry) = event.contexts.entry("os".to_string()) { - if let Some(os) = os_context() { - entry.insert(os); - } - } + if self.add_os + && let Entry::Vacant(entry) = event.contexts.entry("os".to_string()) + && let Some(os) = os_context() + { + entry.insert(os); } if self.add_rust { event diff --git a/sentry-core/src/client/mod.rs b/sentry-core/src/client/mod.rs index 307995115..931abb9d9 100644 --- a/sentry-core/src/client/mod.rs +++ b/sentry-core/src/client/mod.rs @@ -559,10 +559,10 @@ impl Client { sentry_debug!("[Client] called capture_log, but options.enable_logs is set to false"); return; } - if let Some(log) = self.prepare_log(log, scope) { - if let Some(ref batcher) = *self.logs_batcher.read().unwrap() { - batcher.enqueue(log); - } + if let Some(log) = self.prepare_log(log, scope) + && let Some(ref batcher) = *self.logs_batcher.read().unwrap() + { + batcher.enqueue(log); } } @@ -600,15 +600,14 @@ impl Client { return; } - if let Some(metric) = self.prepare_metric(metric, scope) { - if let Some(batcher) = self + if let Some(metric) = self.prepare_metric(metric, scope) + && let Some(batcher) = self .metrics_batcher .read() .expect("metrics batcher lock could not be acquired") .as_ref() - { - batcher.enqueue(metric); - } + { + batcher.enqueue(metric); } } diff --git a/sentry-core/src/hub.rs b/sentry-core/src/hub.rs index b8411173a..6e02942fc 100644 --- a/sentry-core/src/hub.rs +++ b/sentry-core/src/hub.rs @@ -90,11 +90,10 @@ impl Hub { { use_without_client!(f); with_client_impl! {{ - if let Some(client) = self.client() { - if let Some(integration) = client.get_integration::() { + if let Some(client) = self.client() + && let Some(integration) = client.get_integration::() { return f(integration); } - } Default::default() }} } diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 10a60cc3e..48ef50ac6 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -855,16 +855,15 @@ impl Transaction { // Discard `Transaction` unless sampled. if !inner.sampled { - if let Some(transaction) = inner.transaction.take() { - if let Some(client) = inner.client.as_ref() { + if let Some(transaction) = inner.transaction.take() + && let Some(client) = inner.client.as_ref() { client.record_lost_data(&transaction, ClientReportReason::SampleRate); } - } return; } - if let Some(mut transaction) = inner.transaction.take() { - if let Some(client) = inner.client.take() { + if let Some(mut transaction) = inner.transaction.take() + && let Some(client) = inner.client.take() { transaction.finish_with_timestamp(_timestamp); transaction .contexts @@ -894,7 +893,6 @@ impl Transaction { client.send_envelope(envelope) } - } }} } @@ -1100,15 +1098,15 @@ impl Span { if let Some(cookies) = request.cookies { span.data.insert("cookies".into(), cookies.into()); } - if !request.headers.is_empty() { - if let Ok(headers) = serde_json::to_value(request.headers) { - span.data.insert("headers".into(), headers); - } + if !request.headers.is_empty() + && let Ok(headers) = serde_json::to_value(request.headers) + { + span.data.insert("headers".into(), headers); } - if !request.env.is_empty() { - if let Ok(env) = serde_json::to_value(request.env) { - span.data.insert("env".into(), env); - } + if !request.env.is_empty() + && let Ok(env) = serde_json::to_value(request.env) + { + span.data.insert("env".into(), env); } } @@ -1436,12 +1434,11 @@ mod tests { return 1.0; } - if let Some(custom) = ctx.custom() { - if let Some(rate) = custom.get("rate") { - if let Some(rate) = rate.as_f64() { - return rate as f32; - } - } + if let Some(custom) = ctx.custom() + && let Some(rate) = custom.get("rate") + && let Some(rate) = rate.as_f64() + { + return rate as f32; } 0.1 diff --git a/sentry-core/src/scope/real.rs b/sentry-core/src/scope/real.rs index 76482e1b9..7e0cdda51 100644 --- a/sentry-core/src/scope/real.rs +++ b/sentry-core/src/scope/real.rs @@ -282,10 +282,10 @@ impl Scope { event.level = level; } - if event.user.is_none() { - if let Some(user) = self.user.as_deref() { - event.user = Some(user.clone()); - } + if event.user.is_none() + && let Some(user) = self.user.as_deref() + { + event.user = Some(user.clone()); } event.breadcrumbs.extend(self.breadcrumbs.iter().cloned()); @@ -307,18 +307,17 @@ impl Scope { self.apply_propagation_context(&mut event); } - if event.transaction.is_none() { - if let Some(txn) = self.transaction.as_deref() { - event.transaction = Some(txn.to_owned()); - } + if event.transaction.is_none() + && let Some(txn) = self.transaction.as_deref() + { + event.transaction = Some(txn.to_owned()); } if event.fingerprint.len() == 1 && (event.fingerprint[0] == "{{ default }}" || event.fingerprint[0] == "{{default}}") + && let Some(fp) = self.fingerprint.as_deref() { - if let Some(fp) = self.fingerprint.as_deref() { - event.fingerprint = Cow::Owned(fp.to_owned()); - } + event.fingerprint = Cow::Owned(fp.to_owned()); } for processor in self.event_processors.as_ref() { @@ -337,10 +336,10 @@ impl Scope { /// Applies the contained scoped data to fill a transaction. pub fn apply_to_transaction(&self, transaction: &mut Transaction<'static>) { - if transaction.user.is_none() { - if let Some(user) = self.user.as_deref() { - transaction.user = Some(user.clone()); - } + if transaction.user.is_none() + && let Some(user) = self.user.as_deref() + { + transaction.user = Some(user.clone()); } transaction @@ -366,43 +365,43 @@ impl Scope { log.trace_id = Some(self.propagation_context.trace_id); } - if !log.attributes.contains_key("sentry.trace.parent_span_id") { - if let Some(span) = self.get_span() { - let span_id = match span { - crate::TransactionOrSpan::Transaction(transaction) => { - transaction.get_trace_context().span_id - } - crate::TransactionOrSpan::Span(span) => span.get_span_id(), - }; - log.attributes.insert( - "parent_span_id".to_owned(), - LogAttribute(span_id.to_string().into()), - ); - } + if !log.attributes.contains_key("sentry.trace.parent_span_id") + && let Some(span) = self.get_span() + { + let span_id = match span { + crate::TransactionOrSpan::Transaction(transaction) => { + transaction.get_trace_context().span_id + } + crate::TransactionOrSpan::Span(span) => span.get_span_id(), + }; + log.attributes.insert( + "parent_span_id".to_owned(), + LogAttribute(span_id.to_string().into()), + ); } if let Some(user) = self.user.as_ref() { - if !log.attributes.contains_key("user.id") { - if let Some(id) = user.id.as_ref() { - log.attributes - .insert("user.id".to_owned(), LogAttribute(id.to_owned().into())); - } + if !log.attributes.contains_key("user.id") + && let Some(id) = user.id.as_ref() + { + log.attributes + .insert("user.id".to_owned(), LogAttribute(id.to_owned().into())); } - if !log.attributes.contains_key("user.name") { - if let Some(name) = user.username.as_ref() { - log.attributes - .insert("user.name".to_owned(), LogAttribute(name.to_owned().into())); - } + if !log.attributes.contains_key("user.name") + && let Some(name) = user.username.as_ref() + { + log.attributes + .insert("user.name".to_owned(), LogAttribute(name.to_owned().into())); } - if !log.attributes.contains_key("user.email") { - if let Some(email) = user.email.as_ref() { - log.attributes.insert( - "user.email".to_owned(), - LogAttribute(email.to_owned().into()), - ); - } + if !log.attributes.contains_key("user.email") + && let Some(email) = user.email.as_ref() + { + log.attributes.insert( + "user.email".to_owned(), + LogAttribute(email.to_owned().into()), + ); } } } diff --git a/sentry-core/src/session.rs b/sentry-core/src/session.rs index 1238ec800..08bec3f3f 100644 --- a/sentry-core/src/session.rs +++ b/sentry-core/src/session.rs @@ -91,11 +91,11 @@ mod session_impl { let mut is_crash = false; for exc in &event.exception.values { has_error = true; - if let Some(mechanism) = &exc.mechanism { - if let Some(false) = mechanism.handled { - is_crash = true; - break; - } + if let Some(mechanism) = &exc.mechanism + && let Some(false) = mechanism.handled + { + is_crash = true; + break; } } diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 7fc1cd323..8e624d914 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -299,25 +299,25 @@ where // We should only do this if we're capturing stack traces, otherwise the issue title will be `` // as Sentry will attempt to use missing stack trace to determine the title. #[cfg(feature = "backtrace")] - if !exceptions.is_empty() && message.is_some() { - if let Some(client) = sentry_core::Hub::current().client() { - if client.options().attach_stacktrace { - let thread = sentry_backtrace::current_thread(true); - let exception = Exception { - ty: level_to_exception_type(event.metadata().level()).to_owned(), - value: message.take(), - module: event.metadata().module_path().map(str::to_owned), - stacktrace: thread.stacktrace, - raw_stacktrace: thread.raw_stacktrace, - thread_id: thread.id, - mechanism: Some(Mechanism { - synthetic: Some(true), - ..Mechanism::default() - }), - }; - exceptions.push(exception) - } - } + if !exceptions.is_empty() + && message.is_some() + && let Some(client) = sentry_core::Hub::current().client() + && client.options().attach_stacktrace + { + let thread = sentry_backtrace::current_thread(true); + let exception = Exception { + ty: level_to_exception_type(event.metadata().level()).to_owned(), + value: message.take(), + module: event.metadata().module_path().map(str::to_owned), + stacktrace: thread.stacktrace, + raw_stacktrace: thread.raw_stacktrace, + thread_id: thread.id, + mechanism: Some(Mechanism { + synthetic: Some(true), + ..Mechanism::default() + }), + }; + exceptions.push(exception) } if let Some(exception) = exceptions.last_mut() { diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index d48111920..e5285b295 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -549,20 +549,20 @@ impl Envelope { // filter again, removing attachments which do not make any sense without // an event/transaction - if filtered.uuid().is_none() { - if let Items::EnvelopeItems(ref mut items) = filtered.items { - let old_items = mem::take(items); - *items = old_items - .into_iter() - .filter_map(|item| match item { - EnvelopeItem::Attachment(..) => { - filter.on_filtered(item); - None - } - _ => Some(item), - }) - .collect(); - } + if filtered.uuid().is_none() + && let Items::EnvelopeItems(ref mut items) = filtered.items + { + let old_items = mem::take(items); + *items = old_items + .into_iter() + .filter_map(|item| match item { + EnvelopeItem::Attachment(..) => { + filter.on_filtered(item); + None + } + _ => Some(item), + }) + .collect(); } if filtered.items.is_empty() { From 8b5786f660df9ce453519c655261683bea2f73fd Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 24 Jul 2026 15:50:01 +0000 Subject: [PATCH 4/4] ref: Avoid unsound std::env::set_var after edition 2024 `set_var` is unsafe because concurrent environment access is UB on many platforms. Wrapping the old call sites in `unsafe` did not establish that precondition (and the actix example even started a multi-threaded runtime afterward). Remove process-environment mutation from examples/docs/tests, require `RUST_BACKTRACE=1` to already be set for anyhow backtrace tests (CI now provides it), and drop the changelog entry for this work. Related to [#971](https://github.com/getsentry/sentry-rust/issues/971) Related to [RUST-137](https://linear.app/getsentry/issue/RUST-137/bump-rust-edition-to-2024) Co-authored-by: Daniel Szoke --- .github/workflows/ci.yml | 3 +++ .github/workflows/test.yml | 3 +++ CHANGELOG.md | 4 ---- sentry-actix/README.md | 3 --- sentry-actix/examples/basic.rs | 4 ---- sentry-actix/src/lib.rs | 3 --- sentry-anyhow/src/lib.rs | 24 +++++++++++++----------- sentry/src/defaults.rs | 27 +++++++++++++-------------- 8 files changed, 32 insertions(+), 39 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c89e5a172..7e6ac777e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,9 @@ jobs: codecov: name: Code Coverage runs-on: ubuntu-latest + env: + # Keep in sync with test.yml: anyhow backtrace tests require this preset. + RUST_BACKTRACE: "1" steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c8c43953c..735fb5f8c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,9 @@ on: env: RUSTFLAGS: -Dwarnings + # anyhow backtrace capture (and some SDK tests) require this to already be set; + # mutating the process environment from tests via std::env::set_var is unsound. + RUST_BACKTRACE: "1" jobs: test: diff --git a/CHANGELOG.md b/CHANGELOG.md index 89f392721..513383656 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,10 +31,6 @@ - Restored the reqwest transport's pre-0.13 protocol features by disabling HTTP/2 and native-TLS ALPN ([#1258](https://github.com/getsentry/sentry-rust/pull/1258)). -### Internal - -- Updated the Rust edition to 2024 ([#1265](https://github.com/getsentry/sentry-rust/pull/1265)). - ## 0.48.5 ### Fixes diff --git a/sentry-actix/README.md b/sentry-actix/README.md index dfa4b1358..903b21e5b 100644 --- a/sentry-actix/README.md +++ b/sentry-actix/README.md @@ -29,9 +29,6 @@ fn main() -> io::Result<()> { let _guard = sentry::init( sentry::ClientOptions::new().maybe_release(sentry::release_name!()), ); - unsafe { - std::env::set_var("RUST_BACKTRACE", "1"); - } let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() diff --git a/sentry-actix/examples/basic.rs b/sentry-actix/examples/basic.rs index f09a16c33..361bcd761 100644 --- a/sentry-actix/examples/basic.rs +++ b/sentry-actix/examples/basic.rs @@ -1,4 +1,3 @@ -use std::env; use std::io; use actix_web::{App, Error, HttpRequest, HttpServer, get}; @@ -30,9 +29,6 @@ fn main() -> io::Result<()> { .session_mode(sentry::SessionMode::Request) .debug(true), ); - unsafe { - env::set_var("RUST_BACKTRACE", "1"); - } let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 7ac145744..5e5d8d0d8 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -21,9 +21,6 @@ //! let _guard = sentry::init( //! sentry::ClientOptions::new().maybe_release(sentry::release_name!()), //! ); -//! unsafe { -//! std::env::set_var("RUST_BACKTRACE", "1"); -//! } //! //! let runtime = tokio::runtime::Builder::new_multi_thread() //! .enable_all() diff --git a/sentry-anyhow/src/lib.rs b/sentry-anyhow/src/lib.rs index adea9da28..07b4da4be 100644 --- a/sentry-anyhow/src/lib.rs +++ b/sentry-anyhow/src/lib.rs @@ -98,17 +98,23 @@ impl AnyhowHubExt for Hub { } #[cfg(all(feature = "backtrace", test))] -#[allow(unsafe_code)] mod tests { use super::*; + fn anyhow_with_captured_backtrace() -> anyhow::Error { + let err = anyhow::anyhow!("Oh jeez"); + assert_eq!( + err.backtrace().status(), + std::backtrace::BacktraceStatus::Captured, + "run with RUST_BACKTRACE=1 (anyhow captures only when that is preset; \ + tests must not call std::env::set_var)" + ); + err + } + #[test] fn test_event_from_error_with_backtrace() { - unsafe { - std::env::set_var("RUST_BACKTRACE", "1"); - } - - let event = event_from_error(&anyhow::anyhow!("Oh jeez")); + let event = event_from_error(&anyhow_with_captured_backtrace()); let stacktrace = event.exception[0].stacktrace.as_ref().unwrap(); let found_test_fn = stacktrace @@ -124,11 +130,7 @@ mod tests { #[test] fn test_capture_anyhow_uses_event_from_error_helper() { - unsafe { - std::env::set_var("RUST_BACKTRACE", "1"); - } - - let err = &anyhow::anyhow!("Oh jeez"); + let err = &anyhow_with_captured_backtrace(); let event = event_from_error(err); let events = sentry::test::with_captured_events(|| { diff --git a/sentry/src/defaults.rs b/sentry/src/defaults.rs index 538a0ee3c..90cc43132 100644 --- a/sentry/src/defaults.rs +++ b/sentry/src/defaults.rs @@ -28,19 +28,17 @@ use crate::{ClientOptions, Integration}; /// /// # Examples /// ``` -/// unsafe { -/// std::env::set_var("SENTRY_RELEASE", "release-from-env"); -/// } -/// /// let options = sentry::ClientOptions::default(); -/// assert_eq!(options.release, None); /// assert!(options.transport.is_none()); /// /// let options = sentry::apply_defaults(options); -/// assert_eq!(options.release, Some("release-from-env".into())); /// assert!(options.transport.is_some()); /// ``` /// +/// When `SENTRY_RELEASE` / `SENTRY_ENVIRONMENT` / `SENTRY_DSN` are set in the +/// process environment, `apply_defaults` also fills those fields if they were +/// left unset. +/// /// [`AttachStacktraceIntegration`]: integrations/backtrace/struct.AttachStacktraceIntegration.html /// [`DebugImagesIntegration`]: integrations/debug_images/struct.DebugImagesIntegration.html /// [`ContextIntegration`]: integrations/contexts/struct.ContextIntegration.html @@ -127,14 +125,15 @@ mod tests { let opts = apply_defaults(opts); assert_eq!(opts.environment.unwrap(), "explicit-env"); - let opts = apply_defaults(Default::default()); - // I doubt anyone runs test code without debug assertions - assert_eq!(opts.environment.unwrap(), "development"); - - unsafe { - env::set_var("SENTRY_ENVIRONMENT", "env-from-env"); + // Do not call std::env::set_var here: it is unsound if any other thread + // may touch the environment. Cover the env-var path only when already set. + if let Ok(env_from_env) = env::var("SENTRY_ENVIRONMENT") { + let opts = apply_defaults(Default::default()); + assert_eq!(opts.environment.unwrap(), env_from_env); + } else { + let opts = apply_defaults(Default::default()); + // I doubt anyone runs test code without debug assertions + assert_eq!(opts.environment.unwrap(), "development"); } - let opts = apply_defaults(Default::default()); - assert_eq!(opts.environment.unwrap(), "env-from-env"); } }