Many people use Rust for its Safety. It is a great choice for this, with the borrow checking, smart pointers, etc.
But sometimes, we use Rust not for the safety, but for the Tooling and Syntax it provides. We want the cargo
, we want the crates.io
, we want the match
, but we don't actually care about making everything 100% safe.
This is a valid use case of Rust. It is much faster to dabble in unsafety and get something done in minutes than to spend hours trying to get a Safe Solution to your Problem, and sometimes we just don't Care about the safety there, we just need to get things done. However, the Rust community seems Extremely passionate about safety. Sometimes it feels like the idea of Dabbling in transmutation to expose a field you need would get you shot on sight by the safety enjoyers.
But, this is a use case that does indeed exist. For those who don't need all the safety guarantees and just want to get things done, we present void_toolbox
, a collection of unsafe bullshit that instantly obliterates all Rust safetyness the minute you even add it to your dependencies.
Truly void_toolbox
is a collection of powertools for those who don't need safety in their shenaniganery.
Sometimes we want access to some data from all over the Worlds, but we want it dropped when no strong references remain. We can use stuff like Arc<RwLock<T>>
for this.
But what if my code needs multiple mutable borrows of T
? Boom deadlocks Everywhere. Rust prevents this for a reason, but again, this is for the people that don't Care, where it doesn't matter and Jod dammit we are willing to face the consequences if it means Faster Development.
And so we present Pushover
. As the name implies, this thing just does whatever you want.
let thing = Arc::new(Pushover::new(MyStruct { a: 0 }));
let mut ref_1 = thing.write().unwrap(); // API matches RwLock with returning result, but is always Ok
let mut ref_2 = thing.write().unwrap();
// Wow, two mutable references! Praise rust
ref_1.a += 2;
ref_2.a -= 1;
assert_eq!(ref_1.a, 1);
You can use this to destroy all safety guarantees, and also to improve your productivity. Now you can just do whatever and the pushover will listen.
Sometimes we have lifetimery, but we really aren't having the time of our life having to deal with all that. We look at the code and we Know it'll be fine to do a certain thing, but Rust doesn't believe or trust us.
So, new trait, Staticizable
. It's just implemented for T
, and so you can just go ahead and use it on anything.
struct Bullshit<'a> {
value: &'a str,
}
impl<'a> Bullshit<'a> {
fn new(value: &'a str) -> Self {
Bullshit { value }
}
}
let x = "Hello, world!";
let bs = Bullshit::new(x);
let static_bs: &'static Bullshit = bs.staticize();
println!("staticized value: {}", static_bs.value);
Now Anything can be 'static and you can do anything. You are become god
People will say to never use this kind of chicanery in production, but the reality is that people use C/C++ in production all the time, and Rust with void_toolbox
is still a trillion times safer than that. If you use these correctly, it can be fine in production and you aren't going to die.
Imagine a thing in the toolbox called unprivate
. It scans Rust and parses it and expands to recreated structs from another crate/module in yours, and then transmutes from your structs to theirs, thus exposing private fields you need. Absolute cinema