Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete Dart slice borrowing #437

Merged
merged 14 commits into from
Mar 5, 2024

Conversation

Manishearth
Copy link
Contributor

@Manishearth Manishearth commented Feb 29, 2024

This completes the Dart slice borrowing work fixing #421. It adds appendlists for edges that can be passed down for slices to be appended to.

Also fixes #437: I decided that by removing implicit lifetimes from the equation; we can simplify a bunch of code that had to previously worry about lifetime dependencies. Yay!

I believe this technique has sufficient helpers that it will be easy to implement in JS when needed.

This code does not handle nested structs completely correctly. It's a minor thing and I know how to fix it, but at this point this PR is already complicated enough, I'll work on that soon.

Part of #439

@Manishearth Manishearth changed the title [WIP] complete Dart slice borrowing Complete Dart slice borrowing Feb 29, 2024
@Manishearth Manishearth marked this pull request as ready for review February 29, 2024 08:54
//! appropriately: [`StructBorrowInfo::compute_for_struct_field()`] is super helpful for getting a list edges something should get passed down to.
//!
//! Finally, when converting Rust-to-host, the relevant lifetime edges should be proxied down to the final host type constructors who can stash them wherever needed.
//! This is one again a matter of filtering fields by the lifetimes they use, and for nested structs you can use [`StructBorrowInfo::compute_for_struct_field()`].
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: nice explanation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really felt that the existing code was confusing partly because there was nothing telling you where to start. I might document the borowing_fields approach some day.

@@ -26,17 +26,45 @@ final class BorrowedFields {
c = Utf8Decoder().convert(underlying.c._pointer.asTypedList(underlying.c._length));

// ignore: unused_element
_BorrowedFieldsFfi _pointer(ffi.Allocator temp) {
// If this struct contains any slices, their lifetime-edge-relevant objects (typically _FinalizedArenas) will only
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think explanatory comments like this should live in the generating code, rather than the generated code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kiiinda want people to be able to understand what the code does when they poke at it but in this case I get it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed my mind: I think it's useful to have these in the generated code to track things down, especially since which code handles which edges is nontrivial

feature_tests/dart/lib/src/BorrowedFields.g.dart Outdated Show resolved Hide resolved
feature_tests/dart/lib/src/NestedBorrowedFields.g.dart Outdated Show resolved Hide resolved
ParamBorrowInfo::TemporarySlice => false,
ParamBorrowInfo::BorrowedSlice => true,
_ => unreachable!(
"Slices must produce slice ParamBorrowInfo, found {param_borrow_kind:?}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big fan of this error case existing. We already have the type, why does ParamBorrowInfo include the type again?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the different types contain different kinds of borrowing info. I'm not a fan of this case either but it seemed like the cleanest way to get info across, no matter what we do there will be some such assert somewhere

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then should we get the borrow info from the hir::Slice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No because this function computes it all

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, either we have this error case, or we return ParamBorrowInfo as a more structlike thing with is_borrowed and struct_borrow_info fields, with an assertion that struct_borrow_info is none for non-structs

tool/src/dart/mod.rs Outdated Show resolved Hide resolved
Comment on lines +307 to +308
_FinalizedArena.withLifetime(core.List<core.List<Object>> lifetimeAppendArray) : this.arena = ffi2.Arena() {
_finalizer.attach(this, this.arena);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can slightly simplify this by invoking the main constructor

Suggested change
_FinalizedArena.withLifetime(core.List<core.List<Object>> lifetimeAppendArray) : this.arena = ffi2.Arena() {
_finalizer.attach(this, this.arena);
_FinalizedArena.withLifetime(core.List<core.List<Object>> lifetimeAppendArray) : this() {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha! Was wondering if there was syntax for that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope:

  lib/src/lib.g.dart:348:91: Error: Redirecting constructors can't have a body.
  Try removing the body, or not making this a redirecting constructor.
    _FinalizedArena.withLifetime(core.List<core.List<Object>> lifetimeAppendArray) : this() {

@Manishearth Manishearth merged commit 7687c0f into rust-diplomat:main Mar 5, 2024
12 checks passed
@Manishearth Manishearth deleted the dart-struct-appendlists branch March 5, 2024 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants