Проект Rust с названием Immobile types and guaranteed destructors принят. Он убирает из языка два старых допущения: что любой тип можно перемещать в памяти и что любой тип можно забыть через mem::forget без запуска деструктора. Эти допущения встроены в Rust: присваивание перемещает значения, а mem::forget остаётся безопасной функцией. Но некоторым типам это вредит. Самореферентные async-фьючерсы нельзя безопасно перемещать, а текущий Pin кодирует неперемещаемость через места, а не через типы, что сильно усложняет систему. Типам вроде Transaction или ScopedTaskHandle нужно, чтобы деструктор гарантированно отработал, но mem::forget ломает такую гарантию.
Предлагается добавить новые auto-trait'ы: Move, Destruct и Forget. Типы, реализующие !Move, должны сохранять стабильный адрес всё время существования. Это проще, чем Pin, потому что неперемещаемость становится свойством типа, а не места в памяти. Конструкция таких типов будет опираться на работу из #t-lang/in-place-init. Типы, реализующие !Forget, нельзя забыть через mem::forget, поэтому их деструктор гарантированно выполнится. Это делает возможным безопасный scoped spawn: деструктор хэндла джойнит задачу, и так как хэндл нельзя забыть, задача не сможет пережить родительскую область видимости.
Подход повторяет логику иерархии Sized. Раньше Rust считал, что у всех типов есть известный на этапе компиляции размер, и это допущение ослабили. Здесь то же самое проделывают с перемещением и забыванием.
На ближайший год запланированы конкретные шаги. Компиляторную реализацию Move делают @lcnr и @nia-e, RFC — @yoshuawuyts, а тестирование в Linux kernel — @BennoLossin. Linux kernel — важный пользователь Rust с большим количеством самореферентных структур. Также проверят взаимодействие Iterator и !Move: нужно доказать, что генераторные эффекты можно десахарить в impl Trait + !Move, чтобы они поддерживали самоссылки. Дизайн гарантированных деструкторов исследует @nikomatsakis.
Изменения трейта Future в этом году намеренно не трогают. Это единственный стабильный трейт в Rust, который зависит от Pin, и для перехода на Move ему нужна отдельная миграция.
Предложение позиционируется как альтернатива Project Goal 2025H2: Continue Experimentation with Pin Ergonomics. Тот проект хочет добавить в язык pin как элемент в lvalue-выражениях, в паттернах и специальную перегрузку Drop. Авторы нового подхода считают, что проблема не в языке, а в самом Pin, и в итоге хотят отказаться от Pin полностью. Если цель — депрекейт Pin, то делать pin частью языка навсегда не стоит. Поэтому Move — не дополнение к Pin, а его замена.