diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2025-02-24 13:15:39 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-24 13:15:39 +0000 |
| commit | 18c6f22dc53af2257020ec3badf6a5f25de65e72 (patch) | |
| tree | 17d487cd7e51842b545d4dd4e4ab3610b91690ad | |
| parent | 6e2abbfcc353e95534fa01600c65ba24428abfd3 (diff) | |
| parent | d761f9b682c7b38412723aa90a1a571151cdd353 (diff) | |
| download | rust-18c6f22dc53af2257020ec3badf6a5f25de65e72.tar.gz rust-18c6f22dc53af2257020ec3badf6a5f25de65e72.zip | |
Merge pull request #19219 from Veykril/push-rvosplwpwqqt
Vendor `always-assert` into `stdx`
| -rw-r--r-- | src/tools/rust-analyzer/Cargo.lock | 5 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml | 2 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/stdx/Cargo.toml | 3 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/stdx/src/assert.rs | 115 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/stdx/src/lib.rs | 5 |
5 files changed, 122 insertions, 8 deletions
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 01e6a39f7c9..57aafcb1ec7 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -22,9 +22,6 @@ name = "always-assert" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892" -dependencies = [ - "tracing", -] [[package]] name = "anyhow" @@ -1940,13 +1937,13 @@ dependencies = [ name = "stdx" version = "0.0.0" dependencies = [ - "always-assert", "backtrace", "crossbeam-channel", "itertools", "jod-thread", "libc", "miow", + "tracing", "windows-sys 0.59.0", ] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index b8ce2b7430b..64c8afdc1f7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -94,7 +94,7 @@ syntax-bridge.workspace = true [features] jemalloc = ["jemallocator", "profile/jemalloc"] -force-always-assert = ["always-assert/force"] +force-always-assert = ["stdx/force-always-assert"] sysroot-abi = [] in-rust-tree = [ "sysroot-abi", diff --git a/src/tools/rust-analyzer/crates/stdx/Cargo.toml b/src/tools/rust-analyzer/crates/stdx/Cargo.toml index 1ebb48c577a..62c32d68e6f 100644 --- a/src/tools/rust-analyzer/crates/stdx/Cargo.toml +++ b/src/tools/rust-analyzer/crates/stdx/Cargo.toml @@ -14,11 +14,11 @@ doctest = false [dependencies] backtrace = { version = "0.3.67", optional = true } -always-assert = { version = "0.2.0", features = ["tracing"] } jod-thread = "0.1.2" libc.workspace = true crossbeam-channel.workspace = true itertools.workspace = true +tracing.workspace = true # Think twice before adding anything here [target.'cfg(windows)'.dependencies] @@ -28,6 +28,7 @@ windows-sys = { version = "0.59", features = ["Win32_Foundation"] } [features] # Uncomment to enable for the whole crate graph # default = [ "backtrace" ] +force-always-assert = [] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/stdx/src/assert.rs b/src/tools/rust-analyzer/crates/stdx/src/assert.rs new file mode 100644 index 00000000000..91c279798c2 --- /dev/null +++ b/src/tools/rust-analyzer/crates/stdx/src/assert.rs @@ -0,0 +1,115 @@ +// Vendored from https://github.com/matklad/always-assert/commit/4cf564eea6fcf18b30c3c3483a611004dc03afbb +//! Recoverable assertions, inspired by [the use of `assert()` in +//! SQLite](https://www.sqlite.org/assert.html). +//! +//! `never!` and `always!` return the actual value of the condition if +//! `debug_assertions` are disabled. +//! +//! Use them when terminating on assertion failure is worse than continuing. +//! +//! One example would be a critical application like a database: +//! +//! ```ignore +//! use stdx::never; +//! +//! fn apply_transaction(&mut self, tx: Transaction) -> Result<(), TransactionAborted> { +//! let delta = self.compute_delta(&tx); +//! +//! if never!(!self.check_internal_invariant(&delta)) { +//! // Ok, something in this transaction messed up our internal state. +//! // This really shouldn't be happening, and this signifies a bug. +//! // Luckily, we can recover by just rejecting the transaction. +//! return abort_transaction(tx); +//! } +//! self.commit(delta); +//! Ok(()) +//! } +//! ``` +//! +//! Another example is assertions about non-critical functionality in usual apps +//! +//! ```ignore +//! use stdx::never; +//! +//! let english_message = "super app installed!" +//! let mut local_message = localize(english_message); +//! if never!(local_message.is_empty(), "missing localization for {}", english_message) { +//! // We localized all the messages but this one slipper through the cracks? +//! // Better to show the english one then than to fail outright; +//! local_message = english_message; +//! } +//! println!("{}", local_message); +//! ``` + +/// Asserts that the condition is always true and returns its actual value. +/// +/// If the condition is true does nothing and and evaluates to true. +/// +/// If the condition is false: +/// * panics if `force` feature or `debug_assertions` are enabled, +/// * logs an error if the `tracing` feature is enabled, +/// * evaluates to false. +/// +/// Accepts `format!` style arguments. +#[macro_export] +macro_rules! always { + ($cond:expr) => { + $crate::always!($cond, "assertion failed: {}", stringify!($cond)) + }; + + ($cond:expr, $fmt:literal $($arg:tt)*) => {{ + let cond = $cond; + if cfg!(debug_assertions) || $crate::assert::__FORCE { + assert!(cond, $fmt $($arg)*); + } + if !cond { + $crate::assert::__tracing_error!($fmt $($arg)*); + } + cond + }}; +} + +/// Asserts that the condition is never true and returns its actual value. +/// +/// If the condition is false does nothing and and evaluates to false. +/// +/// If the condition is true: +/// * panics if `force` feature or `debug_assertions` are enabled, +/// * logs an error if the `tracing` feature is enabled, +/// * evaluates to true. +/// +/// Accepts `format!` style arguments. +/// +/// Empty condition is equivalent to false: +/// +/// ```ignore +/// never!("oups") ~= unreachable!("oups") +/// ``` +#[macro_export] +macro_rules! never { + (true $($tt:tt)*) => { $crate::never!((true) $($tt)*) }; + (false $($tt:tt)*) => { $crate::never!((false) $($tt)*) }; + () => { $crate::never!("assertion failed: entered unreachable code") }; + ($fmt:literal $(, $($arg:tt)*)?) => {{ + if cfg!(debug_assertions) || $crate::assert::__FORCE { + unreachable!($fmt $(, $($arg)*)?); + } + $crate::assert::__tracing_error!($fmt $(, $($arg)*)?); + }}; + + ($cond:expr) => {{ + let cond = !$crate::always!(!$cond); + cond + }}; + + ($cond:expr, $fmt:literal $($arg:tt)*) => {{ + let cond = !$crate::always!(!$cond, $fmt $($arg)*); + cond + }}; +} + +#[doc(hidden)] +pub use tracing::error as __tracing_error; + +#[doc(hidden)] +pub const __FORCE: bool = cfg!(feature = "force-always-assert"); diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs index 04c2153abf4..8313e1871f1 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs @@ -4,8 +4,10 @@ use std::io as sio; use std::process::Command; use std::{cmp::Ordering, ops, time::Instant}; -pub mod anymap; mod macros; + +pub mod anymap; +pub mod assert; pub mod non_empty_vec; pub mod panic_context; pub mod process; @@ -13,7 +15,6 @@ pub mod rand; pub mod thin_vec; pub mod thread; -pub use always_assert::{always, never}; pub use itertools; #[inline(always)] |
