mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-29 10:58:02 +00:00
Vendor always-assert
This commit is contained in:
parent
6d68c475c7
commit
9a462b7c36
5 changed files with 122 additions and 8 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
|
@ -22,9 +22,6 @@ name = "always-assert"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892"
|
checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892"
|
||||||
dependencies = [
|
|
||||||
"tracing",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
|
|
@ -1922,13 +1919,13 @@ dependencies = [
|
||||||
name = "stdx"
|
name = "stdx"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"always-assert",
|
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"itertools",
|
"itertools",
|
||||||
"jod-thread",
|
"jod-thread",
|
||||||
"libc",
|
"libc",
|
||||||
"miow",
|
"miow",
|
||||||
|
"tracing",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ syntax-bridge.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
jemalloc = ["jemallocator", "profile/jemalloc"]
|
jemalloc = ["jemallocator", "profile/jemalloc"]
|
||||||
force-always-assert = ["always-assert/force"]
|
force-always-assert = ["stdx/force-always-assert"]
|
||||||
sysroot-abi = []
|
sysroot-abi = []
|
||||||
in-rust-tree = [
|
in-rust-tree = [
|
||||||
"sysroot-abi",
|
"sysroot-abi",
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
backtrace = { version = "0.3.67", optional = true }
|
backtrace = { version = "0.3.67", optional = true }
|
||||||
always-assert = { version = "0.2.0", features = ["tracing"] }
|
|
||||||
jod-thread = "0.1.2"
|
jod-thread = "0.1.2"
|
||||||
libc.workspace = true
|
libc.workspace = true
|
||||||
crossbeam-channel.workspace = true
|
crossbeam-channel.workspace = true
|
||||||
itertools.workspace = true
|
itertools.workspace = true
|
||||||
|
tracing.workspace = true
|
||||||
# Think twice before adding anything here
|
# Think twice before adding anything here
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
|
@ -28,6 +28,7 @@ windows-sys = { version = "0.59", features = ["Win32_Foundation"] }
|
||||||
[features]
|
[features]
|
||||||
# Uncomment to enable for the whole crate graph
|
# Uncomment to enable for the whole crate graph
|
||||||
# default = [ "backtrace" ]
|
# default = [ "backtrace" ]
|
||||||
|
force-always-assert = []
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
||||||
115
crates/stdx/src/assert.rs
Normal file
115
crates/stdx/src/assert.rs
Normal file
|
|
@ -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");
|
||||||
|
|
@ -4,8 +4,10 @@ use std::io as sio;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::{cmp::Ordering, ops, time::Instant};
|
use std::{cmp::Ordering, ops, time::Instant};
|
||||||
|
|
||||||
pub mod anymap;
|
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
|
pub mod anymap;
|
||||||
|
pub mod assert;
|
||||||
pub mod non_empty_vec;
|
pub mod non_empty_vec;
|
||||||
pub mod panic_context;
|
pub mod panic_context;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
|
@ -13,7 +15,6 @@ pub mod rand;
|
||||||
pub mod thin_vec;
|
pub mod thin_vec;
|
||||||
pub mod thread;
|
pub mod thread;
|
||||||
|
|
||||||
pub use always_assert::{always, never};
|
|
||||||
pub use itertools;
|
pub use itertools;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue