Skip to content

Commit 9ac739f

Browse files
committed
no_std support in the Rust guest bindings.
This adds no_std support in the Rust guest bindings. Mostly this involves using `core` and `alloc` instead of `std`, but it also involves adding `extern crate alloc;` in a few places, and also adding a `"std"` cargo feature to gen-guest-rust so that the `impl std::error::Error` can be made conditional. This will eventually be useful for generating bindings from the WASI wit files for std itself to use. And, it's useful for experimenting with generating minimal bindings.
1 parent 96b4e3f commit 9ac739f

File tree

5 files changed

+32
-16
lines changed

5 files changed

+32
-16
lines changed

crates/gen-guest-rust/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ doctest = false
1010

1111
[dependencies]
1212
wit-bindgen-core = { workspace = true }
13-
wit-bindgen-gen-rust-lib = { workspace = true }
13+
wit-bindgen-gen-rust-lib = { workspace = true, default-features = false }
1414
heck = { workspace = true }
1515
structopt = { workspace = true, optional = true }
1616

1717
[dev-dependencies]
1818
wit-bindgen-guest-rust = { path = '../guest-rust' }
1919
test-helpers = { path = '../test-helpers', features = ['guest-rust'] }
20+
21+
[features]
22+
default = ["std"]
23+
std = ["wit-bindgen-gen-rust-lib/std"]

crates/gen-guest-rust/src/lib.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -758,14 +758,15 @@ impl FunctionBindgen<'_> {
758758
fn emit_cleanup(&mut self) {
759759
for (ptr, layout) in mem::take(&mut self.cleanup) {
760760
self.push_str(&format!(
761-
"if {layout}.size() != 0 {{\nstd::alloc::dealloc({ptr}, {layout});\n}}\n"
761+
"if {layout}.size() != 0 {{\nextern crate alloc;\nalloc::alloc::dealloc({ptr}, {layout});\n}}\n"
762762
));
763763
}
764764
if self.needs_cleanup_list {
765765
self.push_str(
766766
"for (ptr, layout) in cleanup_list {\n
767767
if layout.size() != 0 {\n
768-
std::alloc::dealloc(ptr, layout);\n
768+
extern crate alloc;\n
769+
alloc::alloc::dealloc(ptr, layout);\n
769770
}\n
770771
}\n",
771772
);
@@ -1231,7 +1232,7 @@ impl Bindgen for FunctionBindgen<'_> {
12311232
assert_eq!(none, "()");
12321233
let operand = &operands[0];
12331234
let invalid = if unchecked {
1234-
"std::hint::unreachable_unchecked()"
1235+
"core::hint::unreachable_unchecked()"
12351236
} else {
12361237
"panic!(\"invalid enum discriminant\")"
12371238
};
@@ -1268,7 +1269,7 @@ impl Bindgen for FunctionBindgen<'_> {
12681269
let ok = self.blocks.pop().unwrap();
12691270
let operand = &operands[0];
12701271
let invalid = if unchecked {
1271-
"std::hint::unreachable_unchecked()"
1272+
"core::hint::unreachable_unchecked()"
12721273
} else {
12731274
"panic!(\"invalid enum discriminant\")"
12741275
};
@@ -1403,12 +1404,12 @@ impl Bindgen for FunctionBindgen<'_> {
14031404
"let {layout} = core::alloc::Layout::from_size_align_unchecked({vec}.len() * {size}, {align});\n",
14041405
));
14051406
self.push_str(&format!(
1406-
"let {result} = if {layout}.size() != 0\n{{\nlet ptr = std::alloc::alloc({layout});\n",
1407+
"let {result} = if {layout}.size() != 0\n{{\nextern crate alloc;\nlet ptr = alloc::alloc::alloc({layout});\n",
14071408
));
14081409
self.push_str(&format!(
1409-
"if ptr.is_null()\n{{\nstd::alloc::handle_alloc_error({layout});\n}}\nptr\n}}",
1410+
"if ptr.is_null()\n{{\nextern crate alloc;\nalloc::alloc::handle_alloc_error({layout});\n}}\nptr\n}}",
14101411
));
1411-
self.push_str(&format!("else {{\nstd::ptr::null_mut()\n}};\n",));
1412+
self.push_str(&format!("else {{\ncore::ptr::null_mut()\n}};\n",));
14121413
self.push_str(&format!("for (i, e) in {vec}.into_iter().enumerate() {{\n",));
14131414
self.push_str(&format!(
14141415
"let base = {result} as i32 + (i as i32) * {size};\n",

crates/gen-rust-lib/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ test = false
1111
[dependencies]
1212
wit-bindgen-core = { workspace = true }
1313
heck = { workspace = true }
14+
15+
[features]
16+
default = ["std"]
17+
std = []

crates/gen-rust-lib/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -828,9 +828,11 @@ pub trait RustGenerator {
828828
self.push_str("}\n");
829829
self.push_str("}\n");
830830
self.push_str("\n");
831-
self.push_str("impl std::error::Error for ");
832-
self.push_str(&name);
833-
self.push_str("{}\n");
831+
if cfg!(feature = "std") {
832+
self.push_str("impl std::error::Error for ");
833+
self.push_str(&name);
834+
self.push_str("{}\n");
835+
}
834836
} else {
835837
self.print_rust_enum_debug(
836838
id,

crates/guest-rust/src/lib.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
use std::fmt;
2-
use std::marker;
3-
use std::mem;
4-
use std::ops::Deref;
1+
#![no_std]
2+
3+
extern crate alloc;
4+
5+
use alloc::boxed::Box;
6+
use core::fmt;
7+
use core::marker;
8+
use core::mem;
9+
use core::ops::Deref;
510

611
#[cfg(feature = "macros")]
712
pub use wit_bindgen_guest_rust_macro::{export, import};
@@ -123,7 +128,7 @@ pub unsafe trait LocalHandle: HandleType {
123128

124129
#[doc(hidden)]
125130
pub mod rt {
126-
use std::alloc::{self, Layout};
131+
use ::alloc::alloc::{self, Layout};
127132

128133
#[no_mangle]
129134
unsafe extern "C" fn cabi_realloc(

0 commit comments

Comments
 (0)