Skip to content

Commit 0781ccd

Browse files
authored
fix(rust): fully qualify Option and Result in macro (#1676)
When expanding the wit `option` and `result` types to rust, they were printed as `Option` and `Result` respectively. This can cause collisions with locally defined types that happen to share the same name. For example: ``` type %result = bool; // should return a result, but is generated returning the local alias no-clobber: func() -> result<_, _>; ``` The generated types for `option` and `result` now expand to `::core::option::Option` and `::core::result::Result`. Signed-off-by: Scott Andrews <scott@andrews.me>
1 parent 4ac8eaa commit 0781ccd

4 files changed

Lines changed: 57 additions & 4 deletions

File tree

crates/rust/src/interface.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,7 +2384,7 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
23842384
self.rustdoc(docs);
23852385
self.push_str(&format!("pub type {name}"));
23862386
self.print_generics(mode.lifetime);
2387-
self.push_str("= Option<");
2387+
self.push_str("= ::core::option::Option<");
23882388
self.print_ty(payload, mode);
23892389
self.push_str(">;\n");
23902390
}
@@ -2395,7 +2395,7 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
23952395
self.rustdoc(docs);
23962396
self.push_str(&format!("pub type {name}"));
23972397
self.print_generics(mode.lifetime);
2398-
self.push_str("= Result<");
2398+
self.push_str("= ::core::result::Result<");
23992399
self.print_optional_ty(result.ok.as_ref(), mode);
24002400
self.push_str(",");
24012401
self.print_optional_ty(result.err.as_ref(), mode);
@@ -3195,14 +3195,14 @@ impl<'a, 'b> wit_bindgen_core::AnonymousTypeGenerator<'a> for AnonTypeGenerator<
31953195
}
31963196

31973197
fn anonymous_type_option(&mut self, _id: TypeId, t: &Type, _docs: &Docs) {
3198-
self.interface.push_str("Option<");
3198+
self.interface.push_str("::core::option::Option<");
31993199
let mode = self.interface.filter_mode_preserve_top(t, self.mode);
32003200
self.interface.print_ty(t, mode);
32013201
self.interface.push_str(">");
32023202
}
32033203

32043204
fn anonymous_type_result(&mut self, _id: TypeId, r: &Result_, _docs: &Docs) {
3205-
self.interface.push_str("Result<");
3205+
self.interface.push_str("::core::result::Result<");
32063206
self.interface.print_optional_ty(r.ok.as_ref(), self.mode);
32073207
self.interface.push_str(",");
32083208
self.interface.print_optional_ty(r.err.as_ref(), self.mode);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ args = ['--disable-run-ctors-once-workaround']
2+
3+
include!(env!("BINDINGS"));
4+
5+
struct Component;
6+
7+
export!(Component);
8+
9+
impl Guest for Component {
10+
fn run() {
11+
let faux_result = false;
12+
let faux_option = true;
13+
match the::test::i::no_clobber(faux_result, faux_option) {
14+
Ok(_) => {}
15+
Err(None) => {}
16+
Err(Some(_)) => {}
17+
};
18+
}
19+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//@ args = ['--disable-run-ctors-once-workaround']
2+
3+
include!(env!("BINDINGS"));
4+
5+
struct Test;
6+
7+
export!(Test);
8+
9+
impl exports::the::test::i::Guest for Test {
10+
fn no_clobber(
11+
_faux_result: exports::the::test::i::Result,
12+
_faux_option: exports::the::test::i::Option,
13+
) -> Result<(), Option<bool>> {
14+
Err(None)
15+
}
16+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package the:test;
2+
3+
interface i {
4+
type %result = bool;
5+
type %option = bool;
6+
7+
no-clobber: func(faux-result: %result, faux-option: %option) -> result<_, option<bool>>;
8+
}
9+
10+
world runner {
11+
import i;
12+
13+
export run: func();
14+
}
15+
16+
world test {
17+
export i;
18+
}

0 commit comments

Comments
 (0)