
Твой код на Rust компилируется, проходит тесты и является UB. Ты просто об этом не знаешь
vibecodingai 38 минут назад Твой код на Rust компилируется, проходит тесты и является UB. Ты просто об этом не знаешь Средний 6 мин 1.3K Rust * Системное программирование * Компиляторы * Мнение Если взять случайный...
Anthropic — What company has the best second artificial intelligence model at the end of June?
В сфере искусственного интеллекта произошло заметное событие. vibecodingai 38 минут назад Твой код на Rust компилируется, проходит тесты и является UB. Ты просто об этом не знаешь Средний 6 мин 1. 3K Rust * Системное программирование * Компиляторы * Мнение Если взять случайный крейт с crates.
io, поставить на него Miri и подождать минут пять, шанс увидеть красное сообщение про undefined behavior где-то в зависимостях стремится к единице. Чаще всего виноват не автор хитрого unsafe-блока ради скорости, а вполне обычная библиотека, которой пять лет, у которой звёзд на гитхабе больше, чем у твоего пет-проекта строчек кода, и которая всё это время спокойно лежит в продакшене. Самое неприятное в этой истории то, что компилятор ничего не скажет.
Технические детали
Бенчмарки покажут красивые наносекунды. А потом LLVM 19 обновится до LLVM 20, поменяет один проход оптимизации, и твой сервис начнёт ронять прод по понедельникам. Чтобы понять, почему так происходит, придётся залезть в три темы, которые в обычной жизни Rust-разработчика не встречаются: pointer provenance, Stacked Borrows и пришедшую им на смену Tree Borrows.
Указатель это не адресСамое вредное заблуждение, которое тащится в Rust из C, звучит так: указатель это число, представляющее адрес в памяти. С точки зрения процессора так и есть. С точки зрения компилятора уже лет двадцать как нет, просто в C про это стесняются говорить вслух, а в Rust решили оформить явно.
У каждого указателя в модели Rust помимо адреса есть невидимый ярлык, называется provenance. Это по сути идентификатор аллокации, из которой указатель родился, плюс набор разрешений на доступ. Когда ты делаешь Box::new(42), рантайм возвращает тебе не просто адрес, а адрес плюс свежий ярлык, привязанный именно к этому боксу.
Отраслевые последствия
Когда ты кастуешь &mut T в *mut T, ярлык наследуется. Когда ты складываешь два числа и пытаешься объявить результат указателем через transmute, ярлыка у получившейся штуки нет, и любое разыменование такого указателя является UB, даже если по битам адрес совпадает с тем, что вернул аллокатор пять строк назад. Проверить это руками просто:fn main() { let a = ; let b = ; let pa = a.
as_ptr(); let pb = b. as_ptr(); let offset = pb as isize - pa as isize; let forged = ; unsafe { println! ("{}", *forged); } } На любом нормальном процессоре forged будет указывать ровно туда же, куда pb.
Программа что-то напечатает. Скорее всего пятёрку. Запусти под Miri, и увидишь сообщение про trying to retag from a pointer that was not derived from this allocation.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





