Skip to content

Commit f6004cd

Browse files
authored
Fix taking owned resource handles in Rust imports (#669)
* Fix taking owned resource handles in Rust imports I went ahead and did a bit more refactoring at the logic here since I think the old conditions aren't as applicable any more (they haven't aged well) Closes #668 * Fix test compilation * Ignore some more resources tests
1 parent 9e20991 commit f6004cd

File tree

7 files changed

+49
-11
lines changed

7 files changed

+49
-11
lines changed

crates/core/src/lib.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ pub struct TypeInfo {
4242

4343
/// Whether or not this type (transitively) has a borrow handle.
4444
pub has_borrow_handle: bool,
45+
46+
/// Whether or not this type (transitively) has an own handle.
47+
pub has_own_handle: bool,
4548
}
4649

4750
impl std::ops::BitOrAssign for TypeInfo {
@@ -52,6 +55,7 @@ impl std::ops::BitOrAssign for TypeInfo {
5255
self.has_list |= rhs.has_list;
5356
self.has_resource |= rhs.has_resource;
5457
self.has_borrow_handle |= rhs.has_borrow_handle;
58+
self.has_own_handle |= rhs.has_own_handle;
5559
}
5660
}
5761

@@ -164,7 +168,10 @@ impl Types {
164168
info.has_resource = true;
165169
}
166170
TypeDefKind::Handle(handle) => {
167-
info.has_borrow_handle = matches!(handle, Handle::Borrow(_));
171+
match handle {
172+
Handle::Borrow(_) => info.has_borrow_handle = true,
173+
Handle::Own(_) => info.has_own_handle = true,
174+
}
168175
info.has_resource = true;
169176
}
170177
TypeDefKind::Tuple(t) => {

crates/go/tests/codegen.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ macro_rules! codegen_test {
1818
(resource_borrow_in_record $name:tt $test:tt) => {};
1919
(resource_borrow_in_record_export $name:tt $test:tt) => {};
2020
(resources_in_aggregates $name:tt $test:tt) => {};
21+
(issue668 $name:tt $test:tt) => {};
2122

2223
($id:ident $name:tt $test:tt) => {
2324
#[test]

crates/rust-lib/src/lib.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -305,12 +305,21 @@ pub trait RustGenerator<'a> {
305305
let lt = self.lifetime_for(&info, mode);
306306
let ty = &self.resolve().types[id];
307307
if ty.name.is_some() {
308-
// If this type has a list internally, no lifetime is being printed,
309-
// but we're in a borrowed mode, then that means we're in a borrowed
310-
// context and don't want ownership of the type but we're using an
311-
// owned type definition. Inject a `&` in front to indicate that, at
312-
// the API level, ownership isn't required.
313-
if (info.has_list || info.has_borrow_handle) && lt.is_none() {
308+
// If `mode` is borrowed then that means literal ownership of the
309+
// input type is not necessarily required. In this situation we
310+
// ideally want to put a `&` in front to statically indicate this.
311+
// That's not required in all situations however and is only really
312+
// critical for lists which otherwise would transfer ownership of
313+
// the allocation to this function.
314+
//
315+
// Note, though, that if the type has an `own<T>` inside of it then
316+
// it is actually required that we take ownership since Rust is
317+
// losing access to those handles.
318+
//
319+
// Check here if the type has the right shape and if we're in the
320+
// right mode, and if those conditions are met a lifetime is
321+
// printed.
322+
if info.has_list && !info.has_own_handle {
314323
if let TypeMode::AllBorrowed(lt)
315324
| TypeMode::LeafBorrowed(lt)
316325
| TypeMode::HandlesBorrowed(lt) = mode
@@ -1032,7 +1041,7 @@ pub trait RustGenerator<'a> {
10321041
TypeMode::AllBorrowed(s) | TypeMode::LeafBorrowed(s) | TypeMode::HandlesBorrowed(s) => {
10331042
s
10341043
}
1035-
_ => return None,
1044+
TypeMode::Owned => return None,
10361045
};
10371046
if info.has_borrow_handle {
10381047
return Some(lt);

crates/teavm-java/tests/codegen.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ macro_rules! codegen_test {
1717
(resource_borrow_in_record_export $name:tt $test:tt) => {};
1818
(same_names5 $name:tt $test:tt) => {};
1919
(resources_in_aggregates $name:tt $test:tt) => {};
20+
(issue668 $name:tt $test:tt) => {};
2021

2122
($id:ident $name:tt $test:tt) => {
2223
#[test]

tests/codegen/issue668.wit

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package test:test
2+
3+
interface test-import {
4+
resource resource-a {
5+
constructor(id: u32)
6+
}
7+
8+
record record-a {
9+
resource-a: resource-a,
10+
resources: list<resource-a>,
11+
}
12+
13+
resource resource-b {
14+
make: static func(record-a: record-a)
15+
}
16+
}
17+
18+
world test-world {
19+
import test-import
20+
}

tests/runtime/ownership/borrowing-duplicate-if-necessary.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl Guest for Exports {
2424
lists::foo(value)
2525
);
2626

27-
thing_in::bar(thing_in::Thing {
27+
thing_in::bar(&thing_in::Thing {
2828
name: "thing 1",
2929
value: &["some value", "another value"],
3030
});
@@ -38,7 +38,7 @@ impl Guest for Exports {
3838
name: "thing 1".to_owned(),
3939
value: vec!["some value".to_owned(), "another value".to_owned()],
4040
},
41-
thing_in_and_out::baz(value)
41+
thing_in_and_out::baz(&value)
4242
);
4343
}
4444
}

tests/runtime/ownership/borrowing.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl Guest for Exports {
2424
lists::foo(value)
2525
);
2626

27-
thing_in::bar(thing_in::Thing {
27+
thing_in::bar(&thing_in::Thing {
2828
name: "thing 1",
2929
value: &["some value", "another value"],
3030
});

0 commit comments

Comments
 (0)