Primary takeaways:
DerefOwned
but for our own types.use
is a postfix syntax, but can’t we just get the compiler to automatically elide .use()
calls in the first place? Why do we need to make it special in the eyes of the compiler - can’t the documentation just make it clear the .use()
might call .clone()
but is not guaranteed to call .clone()
- basically a if last_use { self } else { self.clone() }
.use
kick in automatically for function calling would be annoying and/or idiosyncratic in a lot of places.Copy
but more powerful - IE I don’t want move constructors but I really want to do some extra bookkeeping that Drop
will handle. IE I want Copy
but with Drop
- not necessarily move-with-side-effectsuse
as a keyword parameter feels grafted on - why would you use move
anymore if you can use use
in 90+% of the current code that uses move
? Is 90% a good estimate here?.use
converts <T>
to <O>
is fraught - especially with use
blocks.use
only doing the one instance might be confusing, or might not be. Our generationalbox
CopyType
never needs the extra .use
calls since everything is Copy
and this works out quite nicely. Internal methods would need to borrow T as &T to not need .use
in more places.Use
isn’t Clone
, but rather just a method that prepares an T to be mem-copied as T. The team (dioxus team) isn’t sold on that idea, but the principle here is that .use
makes “room” for allocations (via .clone()
) whereas the deref-owned (signature takes &T and returns &T) makes it harder to do an allocation to return a new boxed T.clone()
where T: Use
.Use
impl for things would effectively enable auto-clone even for large types. This could be Derived
if and only if each field is Use
, and then custom impls would need to explicitly opt-in to a Use
impl that allocates (which is hopefully linted).The primary feelings here are that .use
does address the issue, and it’s likely the concerns about function-calling convenience are understated, but .use
doesn’t let you skip thinking about lifetimes in the way that Copy
does. Should Rust have that power? It certainly would make UI/async/server code easier to write, but more “work” would need to be implicit with more deref-like sugar.
Deref does set a precedent for “spooky action at a distance” (see examples below) but Deref’s signature limits implicit allocations and locks/atomics since Deref is lending. .use
brings in more forms of spooky action:
.use
changes the previous .use
behavior.use
before a use
block may-or-may not trigger work when creating the closure.Drop
is not deterministic based on scope, necessarily, as it might have been before. This shouldn’t be important practically speaking (ie for RC), but it does change Drop
's behavior.This isn’t terrible per se - we already have some spooky action - but there are certainly possibilities for misuse.