you_can::turn_off_the_borrow_checker

Hacker News Top Tools

Summary

Introduces a Rust macro that suppresses borrow checker errors for educational purposes, warning it is unsafe for production use.

No content available
Original Article
View Cached Full Text

Cached at: 05/25/26, 12:46 PM

# turn_off_the_borrow_checker in you_can - Rust Source: [https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html) ## Attribute Macroturn\_off\_the\_borrow\_checker [Source](https://docs.rs/you-can-build-macros/0.0.14/x86_64-unknown-linux-gnu/src/you_can_build_macros/lib.rs.html#33) ``` #[turn_off_the_borrow_checker] ``` Expand description[You can’t “turn off the borrow checker” in Rust](https://steveklabnik.com/writing/you-can-t-turn-off-the-borrow-checker-in-rust), and you shouldn’t want to\.[Rust’s references](https://doc.rust-lang.org/std/primitive.reference.html)aren’t pointers, and the compiler is free to decimate code that tries to use references as though they are\. If you need raw pointer behaviour in Rust, don’t use this, use[Rust’s actual raw pointers](https://doc.rust-lang.org/std/primitive.pointer.html), which don’t make the same aliasing guarantees to the compiler\. However, if you would like to pretend the borrow checker doesn’t exist**for educational purposes and never in production code**, this macro that will suppress many \(though not all\) borrow checker errors in the code it’s applied to\. This shouldn’t break any otherwise\-valid code; the borrow checker doesn’t affect compilation output, only verify input validity\. However, it will allow unsound and unsafe nonsense that will fail unpredictably and dangerously\. This**is not safe to use**\. #### [§](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#example)Example ##### [§](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#without-macro)Without Macro [ⓘ](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#) ``` fn main() { let mut owned = vec![1, 32]; let mut_1 = &mut owned[0]; let mut_2 = &mut owned[1]; //~^ ERROR cannot borrow `owned` as mutable more than once at a time drop(owned); //~^ ERROR cannot move out of `owned` because it is borrowed let undefined = *mut_1 + *mut_2; println!("{undefined}"); } ``` ##### [§](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#with-macro)With Macro ``` #[you_can::turn_off_the_borrow_checker] fn main() { let mut owned = vec![1, 32]; let mut_1 = &mut owned[0]; let mut_2 = &mut owned[1]; //~^ WARNING the borrow checker is suppressed for these references. drop(owned); let undefined = *mut_1 + *mut_2; println!("{undefined}"); } ``` ### [§](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#explanation)Explanation The macro looks for references created in the code by use of the`&`or`&mut`operators or the`ref`and`ref mut`bindings, and wraps them with our[`borrow\_unchecked\(\)`](https://docs.rs/you-can/latest/you_can/fn.borrow_unchecked.html)function to[unbind their lifetimes](https://doc.rust-lang.org/nomicon/unbounded-lifetimes.html), causing the borrow checker to effectively ignore them\. If running on nightly, it adds new warning diagnostic messages for every reference it modifies\. ##### [§](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#expanded)Expanded ``` fn main() { let mut owned = vec![1, 32]; let mut_1 = unsafe { ::you_can::borrow_unchecked(&mut owned[0]) }; let mut_2 = unsafe { ::you_can::borrow_unchecked(&mut owned[1]) }; drop(owned); let undefined = *mut_1 + *mut_2; println!("{undefined}"); } ``` This approached is limited\. It can’t suppress errors resulting from the code illegally composing lifetimes created elsewhere, or references created implicitly\. As a workaround, prefixing`&\*`can sometimes be used to force an explicit reference where one is needed, such as as in the example below\. #### [§](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#example-1)Example ``` #[you_can::turn_off_the_borrow_checker] fn main() { let mut source = Some(1); let inner_mut = &*source.as_ref().unwrap(); let mutable_alias = &mut source; source = None; *mutable_alias = Some(2); if let Some(ref mut inner_a) = source { match source { Some(ref mut inner_b) => { *inner_b = inner_mut + 1; *inner_a = inner_mut + 2; }, None => { println!("none"); }, } } println!("{source:?}"); } ``` ##### [§](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#expanded-1)Expanded ``` fn main() { let mut source = Some(1); let inner_mut = unsafe { ::you_can::borrow_unchecked(&*source.as_ref().unwrap()) }; let mutable_alias = unsafe { ::you_can::borrow_unchecked(&mut source) }; source = None; *mutable_alias = Some(2); if let Some(ref mut inner_a) = source { let inner_a = unsafe { ::you_can::borrow_unchecked(inner_a) }; match source { Some(ref mut inner_b) => { let inner_b = unsafe { ::you_can::borrow_unchecked(inner_b) }; *inner_b = inner_mut + 1; *inner_a = inner_mut + 2; }, None => { println!("none"); }, } } println!("{source:?}"); } ``` ### [§](https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#discussions)Discussions Here are some related discussions, mostly about why you shouldn’t do this: - [https://reddit\.com/s9az4y](https://reddit.com/s9az4y) - [https://internals\.rust\-lang\.org/t/16001](https://internals.rust-lang.org/t/16001) - [https://news\.ycombinator\.com/item?id=30031323](https://news.ycombinator.com/item?id=30031323) - [https://twitter\.com/pcwalton/status/1485718602233704452](https://twitter.com/pcwalton/status/1485718602233704452) - [https://smitop\.com/post/rust\-skip\-borrowck](https://smitop.com/post/rust-skip-borrowck)

Similar Articles

Borrow-checking without type-checking

Lobsters Hottest

A blog post presents a toy language that enforces borrow-checking at runtime without static typing, using cheap reference-counting on the stack to enable interior pointers and single ownership in a dynamically-typed setting.

iddqd, or the hardest kind of unsafe Rust

Lobsters Hottest

This article introduces iddqd, a Rust library that provides maps where keys are borrowed from values, reducing duplication and synchronization issues. It discusses the challenges of writing unsafe Rust code and how the library maintains correctness.

Safe Made Easy Pt.1: Single Ownership is (Not) Optional

Lobsters Hottest

This article introduces a new approach to memory safety based on linear types and abstract interpretation, aiming to eliminate common bugs like use-after-free and memory leaks more ergonomically than Rust.

Scoped Error in Rust

Lobsters Hottest

Kan-Ru Chen introduces `scoped-error`, a new Rust crate that aims to improve error handling ergonomics by scoping context attachment to the module level, addressing issues with existing crates like anyhow and thiserror.