LINUX.ORG.RU

Rust 1.91.0

 ,


0

5

Представлена новая версия языка программирования Rust. Rust – язык программирования общего назначения, который освобождает программиста от ручного управления памятью благодаря механизму владения, без использования сборщика мусора.

Список изменений:

  • aarch64-pc-windows-msvc теперь является платфомой первого уровня поддержки (ранее было второго уровня). По сравнению со вторым уровнем поддержки, первый уровень подразумевает обязательное успешное прохождения всех тестовых наборов на платформе.

  • Добавлена проверка линтера при возвращении из функции «висячего» указателя. Встроенный в компилятор Borrow Checker уже имеет проверку на тот случай, когда возвращается «висячая» ссылка, но это не работало при использовании сырых указателей. Теперь будет сгенерировано предупреждение:

fn f() -> *const u8 {
    let x = 0;
    &x
}
warning: a dangling pointer will be produced because the local variable `x` will be dropped
 --> src/lib.rs:3:5
  |
1 | fn f() -> *const u8 {
  |           --------- return type of the function is `*const u8`
2 |     let x = 0;
  |         - `x` is part the function and will be dropped at the end of the function
3 |     &x
  |     ^^
  |
  = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated
    at the end of the function because nothing is referencing it as far as the type system is
    concerned
  = note: `#[warn(dangling_pointers_from_locals)]` on by default

В разряд стабильного API было переведено:

  • Path::file_prefix
  • AtomicPtr::fetch_ptr_add
  • AtomicPtr::fetch_ptr_sub
  • AtomicPtr::fetch_byte_add
  • AtomicPtr::fetch_byte_sub
  • AtomicPtr::fetch_or
  • AtomicPtr::fetch_and
  • AtomicPtr::fetch_xor
  • {integer}::strict_add
  • {integer}::strict_sub
  • {integer}::strict_mul
  • {integer}::strict_div
  • {integer}::strict_div_euclid
  • {integer}::strict_rem
  • {integer}::strict_rem_euclid
  • {integer}::strict_neg
  • {integer}::strict_shl
  • {integer}::strict_shr
  • {integer}::strict_pow
  • i{N}::strict_add_unsigned
  • i{N}::strict_sub_unsigned
  • i{N}::strict_abs
  • u{N}::strict_add_signed
  • u{N}::strict_sub_signed
  • PanicHookInfo::payload_as_str
  • core::iter::chain
  • u{N}::checked_signed_diff
  • core::array::repeat
  • PathBuf::add_extension
  • PathBuf::with_added_extension
  • Duration::from_mins
  • Duration::from_hours
  • impl PartialEq<str> for PathBuf
  • impl PartialEq<String> for PathBuf
  • impl PartialEq<str> for Path
  • impl PartialEq<String> for Path
  • impl PartialEq<PathBuf> for String
  • impl PartialEq<Path> for String
  • impl PartialEq<PathBuf> for str
  • impl PartialEq<Path> for str
  • Ipv4Addr::from_octets
  • Ipv6Addr::from_octets
  • Ipv6Addr::from_segments
  • impl<T> Default for Pin<Box<T>> where Box<T>: Default, T: ?Sized
  • impl<T> Default for Pin<Rc<T>> where Rc<T>: Default, T: ?Sized
  • impl<T> Default for Pin<Arc<T>> where Arc<T>: Default, T: ?Sized
  • Cell::as_array_of_cells
  • u{N}::carrying_add
  • u{N}::borrowing_sub
  • u{N}::carrying_mul
  • u{N}::carrying_mul_add
  • BTreeMap::extract_if
  • BTreeSet::extract_if
  • impl Debug for windows::ffi::EncodeWide<'_>
  • str::ceil_char_boundary
  • str::floor_char_boundary
  • impl Sum for Saturating<u{N}>
  • impl Sum<&Self> for Saturating<u{N}>
  • impl Product for Saturating<u{N}>
  • impl Product<&Self> for Saturating<u{N}>

Признак const добавлен к следующим функциям:

  • <[T; N]>::each_ref
  • <[T; N]>::each_mut
  • OsString::new
  • PathBuf::new
  • TypeId::of
  • ptr::with_exposed_provenance
  • ptr::with_exposed_provenance_mut

>>> Подробнее

★★★

Проверено: hobbit ()
Последнее исправление: Wizard_ (всего исправлений: 2)
Ответ на: комментарий от tinykey

В Go кросс‐компиляция организована по образу и подобию компилятора C из Plan 9, как и многое другое в Go вообще. Ад с кросс‐компиляцией C на популярных платформах — совместная заслуга gcc и clang (с LLVM вообще), glibc и прочих монстров. В той же NetBSD с ней попроще.

BerlinFall
()
Ответ на: комментарий от chikanuc

Потому что плюсы, особенно на фоне раста, не умеют во владение? Есть чудовищно уродливый костылище - какбе мув семантика, прилепленная изолентой задним числом, и в таком виде оно нафиг не надо. И на уровне типов плюсы знать не знают ни про какое владение, такая же заалиасенная размазня как и в сишке

zurg
()
Ответ на: комментарий от tinykey

Я говорю про системное и прикладное программирование как таковое, причем здесь Си?
Язык сам по себе вторичен, задача первична, а в растишке все наоборот.

И потом какая в Си инфраструктура? Git что-ли? Cargo гиту не альтернатива.

uin ★★★
()
Ответ на: комментарий от mittorn

Так раст и держится на подсчёте ссылок. Весь обмазанный в Rc и Arc.

Циклические ссылки можно руками разрулить. Уж точно проше, чем учить раст.

потенциальный бранч

Современные процессоры правильно угадывают переход в 98% случаях.

ox55ff ★★★★★
()
Ответ на: комментарий от unC0Rr

Угу, с подсчётом ссылок, толстым рантаймом, сборщиком мусора…

Раст точно так же считает ссылки. Это только в хелло ворлдах можно одним боровом обойтись. Дальше рекламные слоганы перестают работать.

Рантайм для подсчёта ссылок не нужен.

ox55ff ★★★★★
()
Ответ на: комментарий от Somebody

В rust похоже, но чуть гибче, он позволяет тулчейны разных версий качать.

tinykey
()
Ответ на: комментарий от BerlinFall

Не важно кто именно виноват, реальность такова, что кросс-компиляция в C это настолько плохо, что об этом легенды ходят. И это мы еще только про тулчейн, мы еще про префикс с зависимостями не говорили. А их тоже надо как-то собирать. В то же время кросс-компиляция в cargo это вопрос вызова двух команд.

tinykey
()
Ответ на: комментарий от uin

Нет, но причем здесь кростулчейн да еще руками?

У меня в команде пять человек, двое на макбуках, один на арче, один на винде и ещё один на никсе. Им всем надо собираться под arm64 и x86_64. Можно страдать с докером, дистрибутивом, собирать пакеты, найти девопса и делать прочее странное. А можно сделать cargo build --target <triplet>. И, поверь мне, последнее всем нравится сильно больше. В этом и прелесть общего пакетного менеджера с общим тулингом – он везде одинаковый, он не требует такого количества возни, нет нужды каждый девбилд через CI прогонять. Красота.

tinykey
()
Ответ на: комментарий от tinykey

В этом и прелесть общего пакетного менеджера с общим тулингом – он везде одинаковый, он не требует такого количества возни, нет нужды каждый девбилд через CI прогонять.

В том‐то и дело, что в Plan 9, о котором я выше писал, смогли организовать вменяемую кросс‐компиляцию без общего пакетного менеджера. Фокус не в нём.

BerlinFall
()
Ответ на: комментарий от BerlinFall

В том‐то и дело, что в Plan 9, о котором я выше писал, смогли организовать вменяемую кросс‐компиляцию без общего пакетного менеджера. Фокус не в нём.

Plan9 это цельная система. Представь ситуацию, когда у тебя есть Linux, твой софт, и у него десять зависимостей, у которых тоже есть свои зависимости. Для того чтобы чтобы все это собрать, тебе, очевидно, надо как-то собрать зависимости. Раработчики вполне могут разрабатывать и не на Linux. Или на каком-то другом Linux. Для сишки это обычно решают докером, где какая-нибудь общая убунта для которой какой-то страдалец собирает все необходимые зависимости нужных версий. В rust это перестало быть проблемой, потому что есть cargo, который все зависимости собирает сам.

tinykey
()
Ответ на: комментарий от mittorn

В своём проекте

Само собой. Просто ты так категорично высказываешься о ненужности и смерти в плюсах, будто речь идет не только о твоем проекте.

Да и про твой проект осталось непонятно, почему не спасает -static-libstdc++?

unsigned ★★★★
()
Ответ на: комментарий от tinykey

поверь мне, последнее всем нравится сильно больше.

Да я не сомневаюсь что у вас там разнообразие, все занимаются кроссборочными отношениями и вам всем это очень нравится.
Только кроссборкой обычно занимаются что бы собирать не для тех архитектур которые поддерживаются растом, а для того железа на котором физически нет возможности это собирать, например coreboot для старых power mac и тому подобное.

Сборочная система раста тут никак не поможет, а частные корпоративные извращения с фреймворками/растами никаким показателем быть не могут, с тем же успехом можете раст на джаву или сишарп заменить, там вообще ничего собирать не надо а безопасность еще и в рантайме обеспечена.

Ну и не говоря уже о том что какое это все отношение имеет к тому о чем я говорил.

uin ★★★
()
Ответ на: комментарий от mittorn

Вам придётся всё цепочку зависимостей вручную собирать и не факт, что соберётся без патчей. Хотя хз, может есть вариант использовать alpine в качестве SDK, не пробовал.

steemandlinux ★★★★★
()
Ответ на: комментарий от uin

Да я не сомневаюсь что у вас там разнообразие, все занимаются кроссборочными отношениями и вам всем это очень нравится.

Ну вот.

Только кроссборкой обычно занимаются что бы собирать не для тех архитектур которые поддерживаются растом, а для того железа на котором физически нет возможности это собирать, например coreboot для старых power mac и тому подобное.

Да нет, у меня вот стоят ARM’овые Ampere Altra и мне нужно под них софт собрать. Абсолютно скучный продакшон в 2025 году.

Ну и не говоря уже о том что какое это все отношение имеет к тому о чем я говорил.

А о чем ты говорил?

tinykey
()
Ответ на: комментарий от tinykey

Да нет, у меня вот стоят ARM’овые Ampere Altra и мне нужно под них софт собрать. Абсолютно скучный продакшон в 2025 году.

И к чему тогда был эти рассказы про макбуки и никсос?
На плюсах тоже в военке пишут кто на чем хочет кто на винде кто на убунте, кто в кутекреаторе, кто вижуал студии, собирать все равно кроссом под специфичную платформу.

А о чем ты говорил?

Про прикладное и системное ПО, где раст в лучшем случае выступает одним из компонентов из за чего сборка превращается в sh-портянку которая запускает сборку нитаких-как-все а потом и мейк/симейк.

uin ★★★
()
Ответ на: комментарий от uin

И к чему тогда был эти рассказы про макбуки и никсос?

Часть команды на них.

Про прикладное и системное ПО, где раст в лучшем случае выступает одним из компонентов из за чего сборка превращается в sh-портянку которая запускает сборку нитаких-как-все а потом и мейк/симейк.

Ну вот у нас прикладное и системнне ПО на расте и портянок нет. Где минусы-то?

tinykey
()
Ответ на: комментарий от ox55ff

Раст точно так же считает ссылки. Это только в хелло ворлдах можно одним боровом обойтись. Дальше рекламные слоганы перестают работать.

Боров контролирует что ты берешь ссылки где надо, он же никуда не девается.

tinykey
()
Ответ на: комментарий от unC0Rr

Раст не считает ссылки. Программист может использовать Rc/Arc, но чаще всего это не нужно.

Зависит от доменной области. Если мы говорим про что-то сложное вроде Linux, то там ссылками обмазано буквально все.

tinykey
()
Ответ на: комментарий от Darfin

А pinned объект передать можно, запретив перемещение и копирование? Ну как в c++ с передачей по ссылке (если удалены конструкторы копирвоания)

mittorn ★★★★★
()
Ответ на: комментарий от BerlinFall

Не забывай ещё про autotools/meson в верооятных зависимостях

mittorn ★★★★★
()
Ответ на: комментарий от ox55ff

Так раст и держится на подсчёте ссылок. Весь обмазанный в Rc и Arc.

Это признак не очень хорошо написанного кода. Шарить данные между разными крупными частями приложения приходится через rc, но на мелком уровне при работе с локальными данными, где как раз и находятся хотспоты, в большинстве случаев можно обойтись без rc.

А бездумное пихание везде rc приводит к просадке производительности и усложняет понимание, где хранятся данные. Хороший пример — тот бенчмарк сгенерированный gpt с первой страницы этой темы, где по факту тестировались не столько мьютексы, сколько работа с Arc, из-за чего растовский вариант проиграл сишному.

Но стоило убрать ненужный подсчет ссылок, и тесты с растовскими мьютексами стали рвать сишные на 10%-12%, несмотря на лишние гарантии, которые дают растовские мьютексы. И никто так и не привел более быстрый сишный вариант.

Darfin
()
Ответ на: комментарий от ox55ff

Не везде предугадывание есть вообще. Вот если хочешь, чтобы твой софт на little ядрах быстро работал - никакого shared_ptr, притом что gc больших тормозов не вызовет

mittorn ★★★★★
()
Ответ на: комментарий от mittorn

А pinned объект передать можно, запретив перемещение и копирование? Ну как в c++ с передачей по ссылке (если удалены конструкторы копирвоания)

Нет. В расте нельзя запретить перемещать данные внутри одного треда. Они всегда перемещаемые, нету никаких операторов перемещения, а значит и запрещать нечего.

Pin это костыль, по факту просто структура в которой находится один указатель на данные. Запретить перемещать данные можно лишь одним способом — переместить данные в какое-то другое место и «забыть про них», оставив для доступа лишь указатель из Pin. Поскольку сам указатель можно перемещать как угодно, а данные находятся по фиксированному значению, получается ситуация, в которой и перемещать можно что угодно, но при этом есть гарантии того, что данные находятся по фиксированному месту.

Но на практике это все нужно очень редко, в основном в растовских асинках при определенных ситуациях.

Darfin
()
Ответ на: комментарий от steemandlinux

Основная проблема в том, что если не использовать хостовую libc, значит не использовать и gl/gles/vulkan/etc
А значит тулкит будет вынужден либо использовать X11, либо писать пиксели из cpu
Тем временем, можно взять ubuntu 12.04 или 14.04, в качестве тулкита взять imgui + glfw/sdl, собрать там и оно будет работать во всех линуксах, включая многие музейные экспонаты, при этом использовтаь opengl для отрисовки

mittorn ★★★★★
()
Ответ на: комментарий от Darfin

Нет. В расте нельзя запретить перемещать данные внутри одного треда. Они всегда перемещаемые, нету никаких операторов перемещения, а значит и запрещать нечего.

Pin как раз это и делает. Сейчас его делают keyword’ом.

tinykey
()
Ответ на: комментарий от Darfin

То есть, написать код, который не будет перемещать структуру на каждый чих (допустим, она не очень маленькая, либо же их много, чтомбы создало большой оверхед) практически нереально?

mittorn ★★★★★
()
Последнее исправление: mittorn (всего исправлений: 2)
Ответ на: комментарий от tinykey

Pin как раз это и делает. Сейчас его делают keyword’ом.

Вот когда сделают, тогда и можно будет об этом говорить. У этого есть куча противников и оно может болтаться в ночнушках годами так ни во что и не родившись

Darfin
()
Ответ на: комментарий от Darfin

Вот когда сделают, тогда и можно будет об этом говорить. У этого есть куча противников и оно может болтаться в ночнушках годами так ни во что и не родившись

А разницы нет. Меня Pin бесит исключительно самим фактом необходимости во что-то оборачивать, но меня и Result этим же бесит. Ok(()) – одна из самых нелепых вещей в программировании, что я вообще видел.

tinykey
()
Ответ на: комментарий от mittorn

То есть, написать код, который не будет перемещать структуру на каждый чих (допустим, она не очень маленькая, либо же их много, чтомбы создало большой оверхед) практически нереально?

Нет, почему. Реализуешь для нее трейт Copy или вызываешь clone() руками и она будет копироваться каждый раз

Darfin
()
Ответ на: комментарий от Darfin

она не очень маленькая

Неправильно прочитал твое сообщение

Darfin
()

Если структура большая, то явно на стеке храниться не будет. А данные в хипе и так неперемещаемы, т.к. все взаимодействие с ними ты осуществляешь через указатели типа Box, Vector, Rc и т.п. С ними пробоем нет в любом случае. О перемещении нужно думать только в том случае, если разговор идет о данных на стеке, которые недолго живут и поэтому их нужно постоянно перемещать.

Darfin
()
Ответ на: комментарий от Darfin

Я же говорю про тот случай когда я хочу избежать переещения/копирования данных. То есть это либо куча мелких объектов (пул?), чуть больше указателя по размеру, либо большие.
В си здесь вопросов не возникает - всё аллоцируется на стеке, либо в куче и дальше работаем только с указателями. А как с этим в rust?
Понятное дело, что владение как раз упрощает ситуацию, где используется std::move, а что в случае, если владение объектом никуда не передаётся? Получится ли удобно с этим работать?

mittorn ★★★★★
()
Ответ на: комментарий от mittorn

В расте есть ссылки, ещё как есть, прямо вот для этого, и это сильно получше будет чем указатели. Вообще у тебя странные представления о растовом мувинге, это высокоуровневое понятие, в реализации не обязательно что-то куда-то будет копироваться

zurg
()
Ответ на: комментарий от zurg

В расте есть ссылки, ещё как есть, прямо вот для этого, и это сильно получше будет чем указатели. Вообще у тебя странные представления о растовом мувинге, это высокоуровневое понятие, в реализации не обязательно что-то куда-то будет копироваться

В Rust implicit move, поэтому если ты не сказал pinned, у тебя нет гарантий, что что-то не будет перемещено.

tinykey
()
Ответ на: комментарий от Darfin

Если структура большая, то явно на стеке храниться не будет. А данные в хипе и так неперемещаемы, т.к. все взаимодействие с ними ты осуществляешь через указатели типа Box, Vector, Rc и т.п. С ними пробоем нет в любом случае. О перемещении нужно думать только в том случае, если разговор идет о данных на стеке, которые недолго живут и поэтому их нужно постоянно перемещать.

Ну как сказать:

struct NullBlkModule {
    _disk: Pin<Box<Mutex<GenDisk<NullBlkDevice>>>>,
}

Это из линуксового rnull.rs.

tinykey
()
Ответ на: комментарий от zurg

Вот именно, что я плохо себе представляю как это должно реализовываться. Если в лоб - то мы перемещаем объект на каждый чих. Там какой-то move elision работает, который заменит перемещение на ссылку если владение дальше никуда не передастся? Звучит вроде логично, но тогда как при написании кода понимать, что будет под капотом?
Здесь мне интересно, будет ли некий c++ код со ссылками без move так же удобен в rust, или же я словлю кучу ограничений вроде запрета мутабельности, либо вероятность подстановки перемещений туда, где их не было

mittorn ★★★★★
()
Последнее исправление: mittorn (всего исправлений: 1)
Ответ на: комментарий от mittorn

Даже если это можно сделать, но код превратится в лапшу с кучей Pin, то это уже не удобно

mittorn ★★★★★
()
Ответ на: комментарий от tinykey

Я про то что нет и гарантий что обязательно будет memcpy при операции мувинга :

let var1 = T::new(); // какой-то тип без трейта Copy
let var2 = var1;

в терминах языка тут полноценный мув из var1 в var2, в реализации - сразу свяжет var2 c результатом T::new()( если других побочных эффектов нет с var1).

zurg
()
Ответ на: комментарий от mittorn

Я не совсем понимаю твоей проблемы.

Принципы программирования на C/C++/Rust абсолютно одинаковые. Данные могут либо лежать в на стеке, либо в хипе (ну еще в области Статических переменных и TLS).

В плюсах нужны операторы перемещения, из-за

  1. то что на объекте из которого данные переместили, в в плюсах все равно вызывается деструктор. А значит при перемещении данных старый объект нужно как-то маркировать/модифицировать, чтобы деструктор на нем отрабатывал адекватно. В расте с этим нет проблем, т.к. раст сам отслеживает перемещения и не вызывает деструкторов на старом объекте из которого данные переместили в другой.

  2. В плюсах разрешены самоссылающиеся объекты (self referencing). Это когда в объекте хранятся данные и хранится ссылка на саммого себя, на один из элементов этих данных. Поэтому при перемещении обьекта в новое место эти ссылки нужно обновить. В расте самоссылающиеся структуры просто запрещены, а значит и нет проблем.

  3. Данные могут быть привязаны к конкретному треду или хранить что-то в tls. И тогда при перемещении в новый тред нужно тоже данные обновлять. В расте можно запретить перемещать объекты между тредами и разруливать такие вещи руками.

Т.е. в принципе раст устроен таким образом, что перемещать можно что угодно и для этого не требуется руками писать операторы перемещения. Перемещение в расте — memcpy всего объекта в новое место + НЕ вызывание деструктора на старом объекте.

Darfin
()
Ответ на: комментарий от Darfin

В расте самоссылающиеся структуры просто запрещены, а значит и нет проблем.

Не совсем, Pin как раз и нужен, чтобы их сделать.

tinykey
()
Ответ на: комментарий от tinykey

Pin не создает самоссылающиеся структуры. Он их эмулирует. Данные выносятся в отдельное место и там лежат неподвижными, тогда как в объекте хранится указатель на эти данные и объект продолжает перемещаться

Darfin
()
Ответ на: комментарий от Darfin

Да не, вроде я как раз всё правильно понимаю, только вот в c++ по умолчанию объекты не перемещаемы, а копирвоание мо.но запретить, так я могу избедать случайного копирования объекта - это будет ошибкой компиляции.
Возможно ли в rust запретить случайное перемещение и какие это ограничения наложит

mittorn ★★★★★
()
Ответ на: комментарий от Darfin

Pin не создает самоссылающиеся структуры. Он их эмулирует. Данные выносятся в отдельное место и там лежат неподвижными, тогда как в объекте хранится указатель на эти данные и объект продолжает перемещаться

А есть ли разница? Pin гарантирует, что указатель на его содержимое остается стабильным.

tinykey
()
Ответ на: комментарий от tinykey

А есть ли разница?

С практической точки зрения может и нет. Но это не самоссылающийся объект, поскольку он раздроблен на несколько частей и нет ссылок на самого себя

Darfin
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.