you_can::turn_off_the_borrow_checker

striking1 pts0 comments

turn_off_the_borrow_checker in you_can - Rust

Docs.rs

you-can-0.0.14

you-can 0.0.14

Permalink

Docs.rs crate page

MIT OR Apache-2.0

Links

Repository

crates.io

Source

Owners

jeremyBanks

Dependencies

you-can-build-macros ^0.0.14

normal

compiletest_rs ^0.8.0

dev

rustc_version ^0.4.0

dev

Versions

100%<br>of the crate is documented

Platform

i686-pc-windows-msvc

i686-unknown-linux-gnu

x86_64-apple-darwin

x86_64-pc-windows-msvc

x86_64-unknown-linux-gnu

Feature flags

docs.rs<br>About docs.rs<br>Badges<br>Builds<br>Metadata<br>Shorthand URLs<br>Download<br>Rustdoc JSON<br>Build queue<br>Privacy policy

Rust

Rust website

The Book

Standard Library API Reference

Rust by Example

The Cargo Guide

Clippy Documentation

This old browser is unsupported and will most likely display funky things.<br>turn_off_the_borrow_checker

you_can<br>Attribute Macro turn_off_the_borrow_checker Copy item path<br>Source<br>#[turn_off_the_borrow_checker]Expand descriptionYou can’t “turn off the borrow checker” in Rust, and you shouldn’t want<br>to. Rust’s references aren’t pointers, and the compiler is free to<br>decimate code that tries to use references as though they are. If you need raw<br>pointer behaviour in Rust, don’t use this, use<br>Rust’s actual raw pointers, which don’t make the same aliasing guarantees<br>to the compiler. However, if you would like to pretend the borrow checker<br>doesn’t exist for educational purposes and never in production code , this<br>macro that will suppress many (though not all) borrow checker errors in the code<br>it’s applied to.

This shouldn’t break any otherwise-valid code; the borrow checker doesn’t affect<br>compilation output, only verify input validity. However, it will allow unsound<br>and unsafe nonsense that will fail unpredictably and dangerously. This is not<br>safe to use .

§Example<br>§Without Macro

ⓘfn main() {<br>let mut owned = vec![1, 32];

let mut_1 = &mut owned[0];<br>let mut_2 = &mut owned[1];<br>//~^ ERROR cannot borrow `owned` as mutable more than once at a time

drop(owned);<br>//~^ ERROR cannot move out of `owned` because it is borrowed<br>let undefined = *mut_1 + *mut_2;<br>println!("{undefined}");<br>§With Macro

#[you_can::turn_off_the_borrow_checker]<br>fn main() {<br>let mut owned = vec![1, 32];

let mut_1 = &mut owned[0];<br>let mut_2 = &mut owned[1];<br>//~^ WARNING the borrow checker is suppressed for these references.

drop(owned);<br>let undefined = *mut_1 + *mut_2;<br>println!("{undefined}");<br>§Explanation

The macro looks for references created in the code by use of the & or &mut<br>operators or the ref and ref mut bindings, and wraps them with our<br>borrow_unchecked() function to unbind their lifetimes, causing the<br>borrow checker to effectively ignore them. If running on nightly, it adds new<br>warning diagnostic messages for every reference it modifies.

§Expanded

fn main() {<br>let mut owned = vec![1, 32];

let mut_1 = unsafe { ::you_can::borrow_unchecked(&mut owned[0]) };<br>let mut_2 = unsafe { ::you_can::borrow_unchecked(&mut owned[1]) };

drop(owned);<br>let undefined = *mut_1 + *mut_2;<br>println!("{undefined}");

This approached is limited. It can’t suppress errors resulting from the code<br>illegally composing lifetimes created elsewhere, or references created<br>implicitly. As a workaround, prefixing &* can sometimes be used to force an<br>explicit reference where one is needed, such as as in the example below.

§Example

#[you_can::turn_off_the_borrow_checker]<br>fn main() {<br>let mut source = Some(1);<br>let inner_mut = &*source.as_ref().unwrap();<br>let mutable_alias = &mut source;

source = None;<br>*mutable_alias = Some(2);

if let Some(ref mut inner_a) = source {<br>match source {<br>Some(ref mut inner_b) => {<br>*inner_b = inner_mut + 1;<br>*inner_a = inner_mut + 2;<br>},<br>None => {<br>println!("none");<br>},

println!("{source:?}");<br>§Expanded

fn main() {<br>let mut source = Some(1);<br>let inner_mut = unsafe { ::you_can::borrow_unchecked(&*source.as_ref().unwrap()) };<br>let mutable_alias = unsafe { ::you_can::borrow_unchecked(&mut source) };

source = None;<br>*mutable_alias = Some(2);

if let Some(ref mut inner_a) = source {<br>let inner_a = unsafe { ::you_can::borrow_unchecked(inner_a) };

match source {<br>Some(ref mut inner_b) => {<br>let inner_b = unsafe { ::you_can::borrow_unchecked(inner_b) };

*inner_b = inner_mut + 1;<br>*inner_a = inner_mut + 2;<br>},<br>None => {<br>println!("none");<br>},

println!("{source:?}");<br>§Discussions

Here are some related discussions, mostly about why you shouldn’t do this:

https://reddit.com/s9az4y

https://internals.rust-lang.org/t/16001

https://news.ycombinator.com/item?id=30031323

https://twitter.com/pcwalton/status/1485718602233704452

https://smitop.com/post/rust-skip-borrowck

source owned you_can rust turn_off_the_borrow_checker borrow

Related Articles