Create a minimal project with "cargo init --unsafe"

Is this possible ?

"Create a minimal project that allows us to use custom allocators without using the "unsafe" keyword in all parts of the project, similar to Zig and C, by executing the command "cargo init --unsafe"."

Objective:

  • Reduce project size.
  • Decrease binary size.
  • Speed up compilation time.
  • Precise control over memory and manual management.

and other benefits for those who need to manually manage memory in their projects.

free is C is UB if you pass it a bad pointer, so we're never going to let you free stuff outside of unsafe contexts.

https://doc.rust-lang.org/std/alloc/trait.Allocator.html#tymethod.allocate is safe, though, so you can allocate in safe code.

(Albeit using that method to allocate in safe code is useless, since you can't use the result in any useful way. But that's what Box<T, CustomAlloc>::new will be for, once custom allocators are fully figured out.)

I believe @fps wants a "globally unsafe" mode, where all code is considered unsafe. I've wanted for a similar thing a few times, in projects where most code is in an unsafe context, and even that which isn't is typically still soundness-relevant because of ambient soundness requirements.

But even in such environments, being able to say that a specific interface is safe — to define safe abstractions even among the unsafe context — is a strong benefit, and in retrospect each of those projects would have turned out worse had they just been ambiently unsafe.

A desirable strength of Rust is that decently written non-obfuscated Rust is generally fairly locally evident as to what the code is doing and what its safety obligations are, if any, at least given the availability of type lookup. If code might be doing unsafe operations without any local indication of such (i.e. the unsafe keyword), then a good deal of this property is lost.

If you absolutely must have something like this, a source preprocessor that adds unsafe blocks everywhere would be your best bet. Nobody is likely to provide such a tool, and the use of said tool would be generally looked down on as violating a core goal of Rust.

4 Likes

Yes, thank you. I have added some of the intended goals of this action to the main post.

You can define a custom #[global_allocator]. Implementing that custom global allocator will probably involve unsafe, but "all parts of the project" besides that can continue to use the safe allocation API, e.g. Box, String, and Vec will continue to present safe allocation APIs.

I'm not sure if this was ever proposed, but it would be interesting to have something like #![unsafe] or maybe #[implictly_unsafe] to mark that everything in a file implictly unsafe.. except maybe by things marked with #[safe] (or maybe even make safe a keyword)

This would still enable fine-grained annotation of safety, but with inverted polarity.

Like,

#![implictly_unsafe]

fn a(x: *mut i32) {
    *x = 1;
}

safe fn b(x: i32) {
    println!("Hello {x}");
}

fn c(mut x: i32) {
    a(&mut x as *mut i32);

    safe {
        b(x); // safe to call
    }
}

Becomes

unsafe fn a(x: *mut i32) {
    unsafe {
        *x = 10;
    }
}

fn b(x: i32) {
    println!("Hello {x}");
}

unsafe fn c(mut x: i32) {
    unsafe {
        a(&mut x as *mut i32);
    }

    b(x); // safe to call
}

But,

This is true, so I'm unsure if this would be a net positive. (however this is sometimes obscured by some #[attributes] being silently unsafe, among other things; the list of unsafe things in Rust is somewhat non-uniform)

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.