kyren / gc-arena

Incremental garbage collection from safe Rust
Creative Commons Zero v1.0 Universal
436 stars 36 forks source link

Change bounds on `Arc` and `Rc` to require 'static instead of `Collect` #83

Closed kyren closed 7 months ago

kyren commented 7 months ago

There is no reason to ever place Collect types inside of Arc or Rc, and this prevents needing an extra #[collect(require_static)].

Aaron1011 commented 7 months ago

There is no reason to ever place Collect types inside of Arc or Rc

Could you have something like Rc<[MyCollectType<'gc>]?

kyren commented 7 months ago

Could you have something like Rc<[MyCollectType<'gc>]?

You could, and it works and doesn't cause memory leaks, but afaik there isn't a reason to ever do that?

It can't escape the arena because it's 'gc... so I can't think of a reason to want to put it in an Rc?

Wanting to change this didn't come out of nowhere, I was working through something with a user and they reached for Rc and I told them not to use it for 'gc types, so I figured the fact that this is allowed was sort of a mild footgun.

kyren commented 7 months ago

@Aaron1011 if you can think of a reason it'd be important I'll keep it, but if we change it it also eliminates needing a #[collect(requires_static)] bound too.

Aaron1011 commented 7 months ago

Ruffle uses an Rc<Vec<CollectType<'gc>>, and uses Rc:make_mut to get mutable access - this would break our use-case.

kyren commented 7 months ago

Ruffle uses an Rc<Vec<CollectType<'gc>>, and uses Rc:make_mut to get mutable access - this would break our use-case.

But what do you need that for? Why doesn't Gc<'gc, Vec<CollectType<'gc>>> work?

I can see the need if it's something generic that holds an Rc<T>, and T can be Collect... is that it?

If Ruffle needs this then I'll drop the PR full stop, I'm just looking to understand really.

kyren commented 7 months ago

I think I just answered my own question by encountering a situation in which Rc<T: Collect> would be useful in piccolo. It can be useful if you need to do a copy or write on a shared object, depending on whether there are any instances of that object alive. It's a little weird if Rc is held in another Gc type and not by the root though because it depends on other Rc clones being garbage collected, but it IS valid. I'll close this, as it's not worth disabling a valid use case.