Skip to content

Commit 54f00cc

Browse files
Complete support for rust 2024 edition (#1206)
* rust codegen tests: check with both edition 2021 and 2024 * Fixes to codegen to support 2024 edition make various extern C blocks unsafe, and their call sites unsafe all rust codegen tests pass for both edition 2021 and 2024. --------- Co-authored-by: Alex Crichton <alex@alexcrichton.com>
1 parent e7656df commit 54f00cc

File tree

4 files changed

+56
-41
lines changed

4 files changed

+56
-41
lines changed

crates/rust/src/bindgen.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
9898
"
9999
#[cfg(target_arch = \"wasm32\")]
100100
#[link(wasm_import_module = \"{module_name}\")]
101-
extern \"C\" {{
101+
unsafe extern \"C\" {{
102102
#[link_name = \"{name}\"]
103103
fn wit_import{tmp}{sig};
104104
}}
105105
106106
#[cfg(not(target_arch = \"wasm32\"))]
107-
extern \"C\" fn wit_import{tmp}{sig} {{ unreachable!() }}
107+
unsafe extern \"C\" fn wit_import{tmp}{sig} {{ unreachable!() }}
108108
"
109109
);
110110
format!("wit_import{tmp}")
@@ -464,21 +464,21 @@ impl Bindgen for FunctionBindgen<'_, '_> {
464464

465465
let result = if is_own {
466466
let name = self.r#gen.type_path(dealiased_resource, true);
467-
format!("{name}::from_handle({op} as u32)")
467+
format!("unsafe {{ {name}::from_handle({op} as u32) }}")
468468
} else if self.r#gen.is_exported_resource(*resource) {
469469
let name = resolve.types[*resource]
470470
.name
471471
.as_deref()
472472
.unwrap()
473473
.to_upper_camel_case();
474-
format!("{name}Borrow::lift({op} as u32 as usize)")
474+
format!("unsafe {{ {name}Borrow::lift({op} as u32 as usize) }}")
475475
} else {
476476
let tmp = format!("handle{}", self.tmp());
477477
self.handle_decls.push(format!("let {tmp};"));
478478
let name = self.r#gen.type_path(dealiased_resource, true);
479479
format!(
480480
"{{\n
481-
{tmp} = {name}::from_handle({op} as u32);
481+
{tmp} = unsafe {{ {name}::from_handle({op} as u32) }};
482482
&{tmp}
483483
}}"
484484
)
@@ -509,8 +509,8 @@ impl Bindgen for FunctionBindgen<'_, '_> {
509509
.unwrap();
510510
let path = self.r#gen.path_to_root();
511511
results.push(format!(
512-
"{async_support}::FutureReader::from_handle_and_vtable\
513-
({op} as u32, &{path}wit_future::vtable{ordinal}::VTABLE)"
512+
"unsafe {{ {async_support}::FutureReader::from_handle_and_vtable\
513+
({op} as u32, &{path}wit_future::vtable{ordinal}::VTABLE) }}"
514514
))
515515
}
516516

@@ -897,10 +897,11 @@ impl Bindgen for FunctionBindgen<'_, '_> {
897897
self.push_str("let ret = ");
898898
results.push("ret".to_string());
899899
}
900+
self.push_str("unsafe { ");
900901
self.push_str(&func);
901902
self.push_str("(");
902903
self.push_str(&operands.join(", "));
903-
self.push_str(");\n");
904+
self.push_str(") };\n");
904905
}
905906

906907
Instruction::AsyncCallWasm { name, .. } => {
@@ -1027,7 +1028,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
10271028
uwriteln!(
10281029
self.src,
10291030
"\
1030-
{func}({});
1031+
unsafe {{ {func}({}) }};
10311032
",
10321033
operands.join(", ")
10331034
);

crates/rust/src/interface.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -224,11 +224,11 @@ unsafe fn _resource_new(val: *mut u8) -> u32
224224
#[cfg(target_arch = "wasm32")]
225225
{{
226226
#[link(wasm_import_module = "[export]{module}")]
227-
extern "C" {{
227+
unsafe extern "C" {{
228228
#[link_name = "[resource-new]{resource_name}"]
229229
fn new(_: *mut u8) -> u32;
230230
}}
231-
new(val)
231+
unsafe {{ new(val) }}
232232
}}
233233
}}
234234
@@ -245,7 +245,7 @@ fn _resource_rep(handle: u32) -> *mut u8
245245
#[cfg(target_arch = "wasm32")]
246246
{{
247247
#[link(wasm_import_module = "[export]{module}")]
248-
extern "C" {{
248+
unsafe extern "C" {{
249249
#[link_name = "[resource-rep]{resource_name}"]
250250
fn rep(_: u32) -> *mut u8;
251251
}}
@@ -602,7 +602,7 @@ pub mod vtable{ordinal} {{
602602
603603
#[cfg(target_arch = "wasm32")]
604604
#[link(wasm_import_module = "{module}")]
605-
extern "C" {{
605+
unsafe extern "C" {{
606606
#[link_name = "[future-new-{index}]{func_name}"]
607607
fn new() -> u32;
608608
#[link_name = "[future-cancel-write-{index}]{func_name}"]
@@ -784,7 +784,7 @@ pub mod vtable{ordinal} {{
784784
785785
#[cfg(target_arch = "wasm32")]
786786
#[link(wasm_import_module = "{module}")]
787-
extern "C" {{
787+
unsafe extern "C" {{
788788
#[link_name = "[stream-new-{index}]{func_name}"]
789789
fn new() -> u32;
790790
#[link_name = "[stream-cancel-write-{index}]{func_name}"]
@@ -2472,7 +2472,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
24722472
#[doc(hidden)]
24732473
pub unsafe fn from_handle(handle: u32) -> Self {{
24742474
Self {{
2475-
handle: {resource}::from_handle(handle),
2475+
handle: unsafe {{ {resource}::from_handle(handle) }},
24762476
}}
24772477
}}
24782478
@@ -2545,7 +2545,7 @@ impl {camel} {{
25452545
#[doc(hidden)]
25462546
pub unsafe fn from_handle(handle: u32) -> Self {{
25472547
Self {{
2548-
handle: {resource}::from_handle(handle),
2548+
handle: unsafe {{ {resource}::from_handle(handle) }},
25492549
}}
25502550
}}
25512551
@@ -2578,7 +2578,7 @@ impl {camel} {{
25782578
#[doc(hidden)]
25792579
pub unsafe fn dtor<T: 'static>(handle: *mut u8) {{
25802580
Self::type_guard::<T>();
2581-
let _ = {box_path}::from_raw(handle as *mut _{camel}Rep<T>);
2581+
let _ = unsafe {{ {box_path}::from_raw(handle as *mut _{camel}Rep<T>) }};
25822582
}}
25832583
25842584
fn as_ptr<T: Guest{camel}>(&self) -> *mut _{camel}Rep<T> {{
@@ -2637,12 +2637,12 @@ impl<'a> {camel}Borrow<'a>{{
26372637
#[cfg(target_arch = "wasm32")]
26382638
{{
26392639
#[link(wasm_import_module = "{wasm_import_module}")]
2640-
extern "C" {{
2640+
unsafe extern "C" {{
26412641
#[link_name = "[resource-drop]{name}"]
26422642
fn drop(_: u32);
26432643
}}
26442644
2645-
drop(_handle);
2645+
unsafe {{ drop(_handle) }};
26462646
}}
26472647
}}
26482648
}}

crates/rust/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ pub unsafe fn invalid_enum_discriminant<T>() -> T {
589589
if cfg!(debug_assertions) {
590590
panic!(\"invalid enum discriminant\")
591591
} else {
592-
core::hint::unreachable_unchecked()
592+
unsafe { core::hint::unreachable_unchecked() }
593593
}
594594
}
595595
",

crates/test/src/rust.rs

+35-21
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ path = 'lib.rs'
142142
}
143143

144144
fn compile(&self, runner: &Runner<'_>, compile: &Compile) -> Result<()> {
145-
let mut cmd = runner.rustc();
145+
let mut cmd = runner.rustc(Edition::E2021);
146146

147147
// If this rust target doesn't natively produce a component then place
148148
// the compiler output in a temporary location which is componentized
@@ -181,15 +181,21 @@ path = 'lib.rs'
181181
}
182182

183183
fn verify(&self, runner: &Runner<'_>, verify: &Verify<'_>) -> Result<()> {
184-
let mut cmd = runner.rustc();
185184
let bindings = verify
186185
.bindings_dir
187186
.join(format!("{}.rs", verify.world.to_snake_case()));
188-
cmd.arg(&bindings)
189-
.arg("--crate-type=rlib")
190-
.arg("-o")
191-
.arg(verify.artifacts_dir.join("tmp"));
192-
runner.run_command(&mut cmd)?;
187+
let test_edition = |edition: Edition| -> Result<()> {
188+
let mut cmd = runner.rustc(edition);
189+
cmd.arg(&bindings)
190+
.arg("--crate-type=rlib")
191+
.arg("-o")
192+
.arg(verify.artifacts_dir.join("tmp"));
193+
runner.run_command(&mut cmd)?;
194+
Ok(())
195+
};
196+
197+
test_edition(Edition::E2021)?;
198+
test_edition(Edition::E2024)?;
193199

194200
// If bindings are generated in `#![no_std]` mode then verify that it
195201
// compiles as such.
@@ -208,7 +214,7 @@ include!(env!("BINDINGS"));
208214
mod core {}
209215
"#,
210216
)?;
211-
let mut cmd = runner.rustc();
217+
let mut cmd = runner.rustc(Edition::E2021);
212218
cmd.arg(&no_std_root)
213219
.env("BINDINGS", &bindings)
214220
.arg("--crate-type=rlib")
@@ -220,23 +226,31 @@ mod core {}
220226
}
221227
}
222228

229+
enum Edition {
230+
E2021,
231+
E2024,
232+
}
233+
223234
impl Runner<'_> {
224-
fn rustc(&self) -> Command {
235+
fn rustc(&self, edition: Edition) -> Command {
225236
let state = self.rust_state.as_ref().unwrap();
226237
let opts = &self.opts.rust;
227238
let mut cmd = Command::new("rustc");
228-
cmd.arg("--edition=2021")
229-
.arg(&format!(
230-
"--extern=wit_bindgen={}",
231-
state.wit_bindgen_rlib.display()
232-
))
233-
.arg(&format!(
234-
"--extern=futures={}",
235-
state.futures_rlib.display()
236-
))
237-
.arg("--target")
238-
.arg(&opts.rust_target)
239-
.arg("-Cdebuginfo=1");
239+
cmd.arg(match edition {
240+
Edition::E2021 => "--edition=2021",
241+
Edition::E2024 => "--edition=2024",
242+
})
243+
.arg(&format!(
244+
"--extern=wit_bindgen={}",
245+
state.wit_bindgen_rlib.display()
246+
))
247+
.arg(&format!(
248+
"--extern=futures={}",
249+
state.futures_rlib.display()
250+
))
251+
.arg("--target")
252+
.arg(&opts.rust_target)
253+
.arg("-Cdebuginfo=1");
240254
for dep in state.wit_bindgen_deps.iter() {
241255
cmd.arg(&format!("-Ldependency={}", dep.display()));
242256
}

0 commit comments

Comments
 (0)