I’ve been banging my head against the wall for a while on this one. The context is that I’m trying to build an embedded VM for 8-bit AVR processors, but the question is not specific to the AVR.
Here’s a stripped down bit of my code:
#[repr(C, packed(1))]
#[derive(Debug)]
struct Chunk<T> {
chunktype: u8,
color: u8,
size: u16,
object: T
}
impl<T> Deref for Chunk<T> {
type Target = T;
fn deref(&self) -> &T {
&self.object
}
}
fn deref16(s: &Chunk<i16>) -> &i16 {
&(s.object)
}
fn deref8(s: &Chunk<i8>) -> &i8 {
&(s.object)
}
playground link
I half understand that a reference pointing to an unaligned address could be bad. (but couldn’t the compiler just generate code that works around this problem, at a performance penalty of course?)
What I don’t understand is why I only get the error on the implementation of Deref
and on deref16
, but the compiler is happy with deref8
??
On the AVR the behaviour is slightly different. It doesn’t seem to be a problem for whatever size I put in a specialised function like defer16
above. Even something like fn deref(s: &Chunk<[u8; 5]>) -> &[u8; 5] { &(s.object) }
is OK.
But.. the generic implementation of Deref
still gives the same error.
It’s an 8 bit machine, so I was expecting that alignment wouldn’t be a problem at all.
Is the compiler unhappy about the generic Deref
because can’t be sure what type T
will be, and unfortunately isn’t smart enough to realise on the AVR everything is properly aligned?
AFAIK Rust doesn’t allow you to pack integers < 8 bits like C does, right?
Also it confuses me why the deref8
version works on the playground, but deref16
doesn’t.