r3-os/r3

Unsound `transmute` in `get` method for type `List`

Closed this issue · 1 comments

impl<Head: 'static + Copy, Tail: ~const Bag> const Bag for List<Head, Tail> {
fn get<T: 'static>(&self) -> Option<&T> {
// Simulate specialization
if TypeId::of::<T>().eq(&TypeId::of::<Head>()) {
Some(unsafe { transmute::<&Head, &T>(&self.0) })
} else {
self.1.get()
}
}

The safe method get used transmute to make conversion from &Head to &T. Here are two problems:

  1. Copy trait bound is not sufficient for us to safely transmute from &Head. Suggest to use trait bound such as Pod.
  2. Transmute has an overloaded return type. If you do not specify the return type it may produce a surprising type to satisfy inference1.

Footnotes

  1. https://doc.rust-lang.org/nomicon/transmutes.html.

TypeId will make sure the reference use same ABI and have same memory layout. The guarantee is strong enough. I will close the issue.