Prevent accessing std?

I've got a project that I'd like to make no_std using the alloc crate, but unfortunately it relies on HashMap, which is not currently provided by alloc. As a stopgap to regressing further from being no_std, I'd still like to at least ensure that the developers on this project don't accidentally take dependencies on more parts of std.

What I'm wondering is: Is there some way that I can make it so that use std::... will fail to compile outside of a particular module? I was thinking of defining a single module in which std is available, re-exporting all of the collections (like HashMap) that I need from that module, and then making std unavailable everywhere else so that developers don't accidentally take more dependencies on it. Is it possible to approximate something like this?

1 Like

For crates I maintain, I usually do this in CI by checking a target that doesn't have std at all, like thumbv6m-none-eabi.

Wouldn't that only work if our crate were truly no_std, which it can't be due to the HashMap dependency?

Oh, I missed that you want this only "outside of a particular module"...

Maybe you can use hashbrown to complete your transition? The OS-dependent randomness for the hasher is the only thing keeping HashMap in std, but using hashbrown directly uses ahash.

Hmmm not a bad idea. I'll see if we have any other std dependencies besides HashMap, but that might work!

We still run into this problem with thiserror, but that might be addressed by Support no_std by IcyDefiance · Pull Request #64 · dtolnay/thiserror · GitHub.

If you have control over the source code, can you switch it over to alloc::collections::BTreeMap?

I feel like that would be a lot easier than trying to enforce "you can't use anything from std other than HashMap".

Unfortunately the HashMaps are needed for performance reasons. We'd rather make the code a bit ugly in one module than take the performance hit.


Oh wow, great idea! I assume that allows the top-level crate to be no_std?

Exactly, that part did not fit on the screenshot :sweat_smile: : it is precisely because the top-level crate is
#![no_std], that the line use ::std::process::abort fails.

You could even go one step further, and name this hackish shim crate alloc in the Cargo.toml, make it reexport all of ::alloc contents + this collections module from std, so as to make a future transition to a true no_std but alloc-based crate as smooth as possible


This was a great suggestion! I implemented it in

1 Like

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