My Idea to buff no_std

Hello People

i don't have the immediate need for this but maybe some time in the future such a concept may be useful do somebody, maybe.

However i am still very interested in what the other souls think towards this Idea:

#![no_std_fs]

extending the classic Version to the cleanest small subset or breakdown that is harmonic to how no_std works.

#![no_std_fs] #![no_std_net] #![no_std_time] #![no_std_env] #![no_std_process]

Because no_std is such "Hammer" that i saw only very few people resort to it and usually there is always like some gradient to the tool-age available, wherever really i have seen solutions, there was some Options to it.

Thank you and have a nice evening,

Jonas

We don't introduce features just because we think they're cool. The "Motivation" section is the most important in the RFC template.

That being said, what will this give? Almost all targets either have operating systems and then they have everything, or they don't and then they have nothing, and if they have something it's in special drivers and not the job of std. The only exceptions I know are non-WASI WASM (that pretends to have std but mocks most function), and UEFI which is a strange target.

2 Likes

I found that we had a long time ago, a proposal here in the Forum. He elaborated that way better from the get-go.

Suppose I have a parser/codec/algorithm library! Uses are Vec, String, HashMap, Arc and more, so making it no_std buys me very little and imposes quite a bit of work.

Rust Reference itself describes no_std as useful when the platform lacks std, as well as when code is purposefully not using capabilities of the standard library, explicitly mentioning FS and NET.

And if you for example decide, to build a system or structure a system, you would have milestones to lift and would never forget about where you would need to not have that particular STD in, to me that's way more important to maintain then reexport std or other hacks.

STD is perhaps a nice flat baseline but usually no_std lets me reject the entire opaque platform abstraction; I want a way to reject individual opaque parts of it. After all i have absolutely no clue without reading eventually into source-code that i don't even have available. So i don't know whats going on and i just wants to partly contain that:

Because i cant believe you on the point that there is Everything or Nothing, that is what we have right now, with the contemporary no_std solution that should be perhaps reshaped.

  1. A platform having FS/NET/process support does not mean every crate should be allowed to silently grow those dependencies, for example there would be no unexpected execution in some part of FS where you would not expect that. Okay just because the Idea maps to Itself does not make it that better but:

  2. no_std is too coarse when the real invariant is only “this layer must never touch the filesystem/network/environment.” There is not all or nothing, i have seen plenty Platforms that have STD for File systems but just no sense of Network, after all Rust is as well for Low-Level Hardware and Driver development.

  3. Compiler-enforced partial std boundaries turn architecture from documentation into something CI can actually preserve for years. We would never regress a Library with that on top.

  4. Without that, one innocent std::fs::read, std::env::var, SystemTime::now, or Command::new can quietly collapse a boundary nobody remembered was supposed to exist. And That is my main point about it, that the no_std is so great in how it can achieve the no_std assumptions that i just would assume that we can as well just consider: I love the Path where as env is just not supported with all the assumptions jet.

After all, as soon as you stack 1 Layer on top of your completely fine std Abi platform code, suddenly you realise that it can not do it as "expected" and there you have the hidden STD contract: One does not simply "std".

Thank you for that perspective or yours, that is what i believe it will give.

I'm pretty sure you misread the reference. It does say this, but I'm pretty sure the meaning is not "a crate which wants to guarantee it won't use std by mistake" (why will it want that? Furthermore it's not really a guardrail as it's too easy to import a std-using dependency by mistake), but for a crate that does not need the capabilities of std, and wants to be available to no_std users. That is, the reference reads: use no_std either if you must use it (your target doesn't support std), or you don't need it and wants to support users that can't use it.

A (non-IO-performing) parser/codec/algorithm is actually a perfect case for no_std. From all items you listed, only HashMap is not available with core + alloc, and that is due to an implementation limitation that we hope will be lifted in the future.

3 Likes

Note that because people had precisely this problem, the alloc crate was introduced; this is a subset of std that assumes that you have a heap allocator available.

You can thus write no_std code that allocates memory, using Vec, String, Arc, Box etc, without also depending on the rest of std (processes, networking, file I/O etc). If there's things in std that should be in alloc, then the usual procedure for Rust standard library improvements can be used to move things from std to alloc.

When there's a genuine need for another subset of std - noting that (for example) the abstract bits of std::io like the Read trait are candidates for moving to core - then the Rust RFC process can be used to propose the API surface of this second subset, and get consensus on what to do.

If you wanted to make this happen, you could go over the contents of std, and go through the RFC process to get (say) a filesystem, a network, a process, a wallclock crate and whatever others you think are needed. Starting point for that would be a "pre-RFC" here for the first no_std subset crate you want to introduce, so that people who care about this can work with you on the API surface of your new crate - but you'll need a motivating example of code where it "ought" to be no_std, but can't be because you need some APIs from std.

The difference is that there are many embedded systems with no OS but with an allocator, but a system that has, say, only filesystem access is very rare (as I said an example is UEFI - however I don't think it justifies splitting std).

I'm not sure that there's sufficient motivation for a further subset of std either, but that's what the Pre-RFC would be for - what are you splitting out, what motivates this, what are the drawbacks of doing it this way etc, what alternatives are there etc. Basically all the questions that get brought up by the RFC template.

This is especially true since it is possible to mix std and no_std crates. If it's just about restricting what people can do on platforms that implement all of std, it would be possible to have a set of crates.io crates that provide the filesystem interface, the network interface etc, for no_std crates that want to opt-in to restricted subsets of std - so you could have a crate called something like no_std_add_filesystem that depends on std and re-exports the "right" bits of std::io and std::fs, but none of std::net.

I had a walk in the Park and i was thinking about the matter.

See, we will not have anything that appears to be automatically just better, no matter what we apply to the no_std concept, everything seems just well possible.

Therefore i will gladly read here and maybe actually have some time the endurance to push this to a worth while actual RFC in the meantime i am thankful for all the viewpoints:

If some person does not see my particular use-cases now and then, that's legit to me.

An important thing to note here: most open source projects are not limited by the availability of good ideas, but by the number of people willing and able to do the work needed to go from good idea to great implementation.

The Rust project will help you make an implementation great, given that you've shown willingness to learn and you've got the time and enthusiasm needed to put in the hard work; but if you can't (at least) line up someone to do the hard work, the unfortunate effect is that your ideas won't go anywhere.

This is a big chunk of why there's the whole RFC process (with pre-RFC here if you're not confident that your idea is already perfect). By going through the process and demonstrating that you're willing to take feedback, you're setting the stage for someone to help you produce the best possible outcome for the project as a whole, and demonstrating that you're not just coming in with a good idea and then hoping someone unidentified does the work.

2 Likes