Начну пожалуй с того, что в первом примере у Вас UB (undefined behavior):
#[no_mangle]
pub fn test() {
// Вот тут на стеке выделено 4 байта
let mut idx: i32 = 10;
// Указатель на эти 4 байта
let ptr = &mut idx as *mut i32;
// По сути указатель на те же 4 байта, но на деле указатель на 40 байт
let buffer = unsafe { core::slice::from_raw_parts_mut(ptr, 10) };
// И тут мы работаем с этими 40 байтами,
// но нормальные из них только 4 байта в начале,
// а остальные смотрят в глубь стека и меняют его
// то есть перетирают адрес возврата и данные на стеке вызвавшей функции
for pixel in buffer.iter_mut() {
*pixel = 0x7d2b7500;
}
}
То есть после завершения данная функция должна не вернуться в вызывающую функцию, а передать управление непонятно куда.
Ну и еще один момент, это оптимизация, данная функция не имеет сайд эффектов и ничего не возвращает. После инлайна функции
core::slice::from_raw_parts_mut
и метода
Iterator::iter_mut
компилятор вполне может понять, что данный код не имеет сайд эффектов, а значит бесполезен и его можно вырезать. Вот собственно он его и вырезает.
Во втором же примере у нас есть сайд эффект - изменение данных по указателю пришедшему извне через аргументы.
P.S. Во втором примере кстати тоже можно увидеть работу оптимизации, цикл из 10 итераций, пишущих i32 в смещение по указателю, был заменен на обычные 5 записей i64 в смещение по указателю.