Skip to content

Commit

Permalink
Refactor how Rust handles ownership
Browse files Browse the repository at this point in the history
This commit is the next in a long line of refactors to try to model how
the Rust generator handles ownership. The Rust generator has an
`ownership` knob for deciding how to render types. The Rust generator
additionally models ownership of resources/lists in params/results of
imports/exports. Putting all of this together has led to many attempts
to wrangle this in a form that's understandable but every time a bug
comes up I feel like I don't understand what's going on. I've made
another attempt in this commit.

Here the goal is to centralize knowledge about types as much as
possible. Instead of being spread out over a few methods everything is
hopefully now centralized in a single type and a single "main method".
All other little pieces stem from these two and are modeled to be
relatively simple compared to the "main method". Whether or not this
stands the test of time we'll see.

This does change generated code in some situations as can be seen by the
test that was updated. Nothing major should be changed, but a few more
borrows are now required in places which probably should have been
borrows before.

More comments are found in the code about specific changes made here.
  • Loading branch information
alexcrichton committed Feb 17, 2024
1 parent 785edc9 commit cc87a1a
Show file tree
Hide file tree
Showing 7 changed files with 532 additions and 349 deletions.
66 changes: 32 additions & 34 deletions crates/rust/src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,41 +435,39 @@ impl Bindgen for FunctionBindgen<'_, '_> {

let dealiased_resource = dealias(resolve, *resource);

results.push(
if let Direction::Export = self.gen.gen.resources[&dealiased_resource].direction
{
match handle {
Handle::Borrow(_) => {
let name = resolve.types[*resource]
.name
.as_deref()
.unwrap()
.to_upper_camel_case();
let rt = self.gen.gen.runtime_path();
format!(
"{rt}::Resource::<{name}>::lift_borrow({op} as u32 as usize)"
)
}
Handle::Own(_) => {
let name = self.gen.type_path(dealiased_resource, true);
format!("{name}::from_handle({op} as u32)")
}
let result = if let Direction::Export =
self.gen.gen.resources[&dealiased_resource].direction
{
match handle {
Handle::Borrow(_) => {
let name = resolve.types[*resource]
.name
.as_deref()
.unwrap()
.to_upper_camel_case();
let rt = self.gen.gen.runtime_path();
format!("{rt}::Resource::<{name}>::lift_borrow({op} as u32 as usize)")
}
} else if prefix == "" {
let name = self.gen.type_path(dealiased_resource, true);
format!("{name}::from_handle({op} as u32)")
} else {
let tmp = format!("handle{}", self.tmp());
self.handle_decls.push(format!("let {tmp};"));
let name = self.gen.type_path(dealiased_resource, true);
format!(
"{{\n
{tmp} = {name}::from_handle({op} as u32);
{prefix}{tmp}
}}"
)
},
);
Handle::Own(_) => {
let name = self.gen.type_path(dealiased_resource, true);
format!("{name}::from_handle({op} as u32)")
}
}
} else if prefix == "" {
let name = self.gen.type_path(dealiased_resource, true);
format!("{name}::from_handle({op} as u32)")
} else {
let tmp = format!("handle{}", self.tmp());
self.handle_decls.push(format!("let {tmp};"));
let name = self.gen.type_path(dealiased_resource, true);
format!(
"{{\n
{tmp} = {name}::from_handle({op} as u32);
{prefix}{tmp}
}}"
)
};
results.push(result);
}

Instruction::RecordLower { ty, record, .. } => {
Expand Down
Loading

0 comments on commit cc87a1a

Please sign in to comment.