@@ -466,3 +466,46 @@ benefit from contravariant lifetimes joining the two together.
466466I expect it might bring some surprising and positive results! Either that, or I
467467am being a total crackpot. I guess time and effort will tell. Until then, stay
468468contrary!
469+
470+ ### Update (11th of January, 2026)
471+
472+ This post received some excellent feedback / pushback on
473+ [ Lobsters] ( https://lobste.rs/s/jydyuw/garbage_collected_handles_are_lifetime ) .
474+ While I do not agree with what is, perhaps, the thrust of the feedback
475+ ("contravariance has nothing to do with GC or self-reference" or in other words
476+ that this entire approach is flawed), the following discussion did strongly
477+ underline a meaningful point: a fully safe representation of unrooted handles is
478+ possible as shown by [ ` gc-arena ` ] ( https://github.com/kyren/gc-arena ) and it
479+ relies on _ invariance_ which can be viewed as a combination of covariance and
480+ contravariance.
481+
482+ In terms of contravariant references, this is exactly what I get with the
483+ combination of a contravariant reference and a covariant reference of a proof
484+ value:
485+
486+ ``` rust
487+ let handle : Handle <'_ > = ... ; // Contravariant.
488+ let proof : & Proof = ... ; // Covariant.
489+ handle . join (proof ); // Invariant, sort of.
490+ ```
491+
492+ The difference between the proven ` gc-arena ` solution based on invariance and my
493+ approach based on contravariant references (currently unsound/incomplete,
494+ requiring runtime checks or new Rust features to make it safe) is, I believe
495+ (again without proof), that the invariant approach gives the "least upper bound"
496+ of the solution with a lot of limitations (basically, garbage collection must
497+ happen outside of the interpreter's Rust call stack thereby forcing a stackless
498+ interpreter design, and heap data cannot be accessed mutably even in a
499+ single-threaded system; I recommend reading
500+ [ this] ( https://kyju.org/blog/rust-safe-garbage-collection/ ) blog post and its
501+ [ follow-up] ( https://kyju.org/blog/piccolo-a-stackless-lua-interpreter/ ) for more
502+ details) whereas the contravariant approach seems to give the "greatest lower
503+ bound" with less limitations (garbage collection can happen inside the
504+ interpreter's Rust call stack and the heap can be accessed mutably but of course
505+ only within Rust's normal aliasing rules).
506+
507+ That being said, if you want a solution that works and gives compile-time
508+ guarantees today in a fully sound way, ` gc-arena ` is your ticket to victory. Me?
509+ I plan on researching where this contrarian road takes me, and until I find a
510+ solution (or a dead-end wall that cannot be overcome) I will accept some runtime
511+ checks.
0 commit comments