1

This code works:

let mut b: Vec<*const SimpleStruct> = Vec::with_capacity(a.len());
for val in a.iter() {
    b.push(val);
}

This code does not work:

let b: Vec<*const SimpleStruct> = a.iter().map(|val| val).collect();

Playground

Why is this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jonathan Woollett-light
  • 2,813
  • 5
  • 30
  • 58

1 Answers1

2

When you push &SimpleStruct to a Vec<*const SimpleStruct>, Rust knows that it can coerce the reference into a pointer. However, when you collect it, Rust is trying to coerce a Vec<&SimpleStruct> to a Vec<*const SimpleStruct>, which it can't do, so you should be more explicit:

let b: Vec<*const SimpleStruct> = a.iter().map(|val| val as *const SimpleStruct).collect();

or

let b: Vec<*const SimpleStruct> = a.iter().map(|val| -> *const SimpleStruct { val }).collect();
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • See also [Use Option::map to Box::new a trait object does not work](https://stackoverflow.com/q/48864045/155423); [Why are iterator items which are references not cast to a trait object reference?](https://stackoverflow.com/q/54520085/155423). – Shepmaster Jun 23 '20 at 18:33
  • 1
    `let b: Vec<_> = ...` would be both shorter, less redundant, and more idiomatic. – Shepmaster Jun 23 '20 at 18:35