Closed Kry-Vosa closed 1 year ago
Even better might be another impl with qcell::LCell, mainly to point users to the existing zero-cost abstraction if they really need it.
Cell<Option<&mut I2c>>
pointing to the 1st, and you have to ensure the 1st outlives the 2nd.isize
RefCell borrow flag, but you add a pointer that you didn't have before. It's a tie if the i2c size is a multiple of usize
size, it's a slight win otherwise due to alignment but in practice it's unlikely to make a difference (allocations are likely to get rounded up to usize if the thing coming after needs usize alignment). See https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ed5a2507ea3503f2526ea2553333c503So I don't think it's worth it, I'd prefer to keep the simpler, more idiomatic RefCell.
Also, note that nothing prevents external crates from implementing SpiDevice
with Cell<Option>
or LCell
or anything else. It doesn't have to be in embedded-hal-bus
, it'll still interoperate with the ecosystem fine thanks to the SpiDevice
trait.
You are indeed correct and I'm dumb. Sorry for the wasted time.
However I believe the point with LCell
still stands, it would be nice if embedded-hal-bus
provided zero-cost way of sharing buses instead of forcing developers to look elsewhere.
The whole idea is in the title: Since we do not need multiple immutable borrows at the same time, we can use just
Cell<Option<&mut I2c>>
."Borrowing" the reference is just:
(Or something more fancy if you wish)
As for why should we do that, it should (thanks to null-pointer optimization) save a whole
isize
of memory, which might be actually meaningful on targets like Arduino (or AVR in general), where memory is scarce and likelihood of multiple I2C drivers high.