LINUX.ORG.RU

Rust 1.22.0 и 1.22.1

 


2

7

Команда языка Rust с радостью представляет две версии языка Rust, 1.22 и 1.22.1. Rust — это системный язык программирования, который нацелен на безопасность, скорость выполнения и параллельное исполнение.

Подождите, две версии? В последний момент мы нашли баг на новой macOS High Sierra и по разным причинам решили выпустить 1.22 как обычно, а также выпустить пропатченный 1.22.1. Баг был найден в Cargo и влияет он только на пользователей macOS High Sierra.

Если у вас уже есть предыдущая версия Rust, обновите ее с помощью:

$ rustup update stable

Если у вас еще нет rustup, то вы можете скачать его. Детальный патчноут.

Что нового в 1.22.0 и 1.22.1

Главным нововведением является возможность использования ? для Option<T>! Примерно год назад мы представляли оператор ? для работы с Result<T, E>. С того момента началась дискуссия о будущем этого оператора. Должен он использоваться только с Result<T, E>? Должен ли он быть расширяем пользователем? Должен ли он использоваться с Option<T>?

В Rust 1.22 базовое использование данного оператора с Option<T> было стабилизировано. Теперь данный код будет компилироваться:

fn try_option_some() -> Option<u8> {
    let val = Some(1)?;
    Some(val)
}
assert_eq!(try_option_some(), Some(1));

fn try_option_none() -> Option<u8> {
    let val = None?;
    Some(val)
}
assert_eq!(try_option_none(), None);

Однако его функционал все еще ограничен. Вы не сможете писать код, который совмещает использование оператора ? для Option<T> и Result<T, E> в одной функции, например. Это будет возможно в будущем и уже доступно в nightly версии. Ждите новостей об этом операторе в будущем.

Типы, которые реализуют Drop теперь могу использоваться с const и static:

struct Foo {
    a: u32
}

impl Drop for Foo {
    fn drop(&mut self) {}
}

const F : Foo = Foo { a : 0 };
static S : Foo = Foo { a : 0 };

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

Также, некоторые маленькие изменения:

Два последних изменения в компиляторе ускорят компиляцию в debug режиме. У нас нет точных чисел, но, как обычно, время компиляции очень важно для нас, поэтому мы продолжим работать в этом направлении в будущем.

T op= &T теперь работает для примитивов:

let mut x = 2;
let y = &8;

// Теперь это будет работать
x += y;

Ранее вам нужно было писать x += *y для разыменовывания.

Улучшены бектрейсы на MacOS.

Теперь вы можете создавать compile-fail тесты в Rustdoc:

/// ```compile_fail
/// let x = 5;
/// x += 2; // shouldn't compile!
/// ``

Заметьте, что данные тесты могут опасны, потому что теперь код, который не компилировался, будет компилироваться. Например, оператор ?: код с ним не будет компилироваться в 1.21, но успешно скомпилируется на 1.22 и, возможно, сломает ваши тесты.

Также, мы перестаем поддерживать le32-unknown-nacl. Google уже отказались от поддержки PNaCl, направив силы на поддержку WebAssembly.

Стабилизация библиотеки

Несколько новых API были стабилизированы:

И другие.

Cargo

Если у вас есть какие-либо примеры для пользователей, то теперь Cargo может собирать их в поддиректории в examples, которая содержит main.rs.

Теперь Cargo может использовать git-репозитории для получения зависимостей.

>>> Полный патчноут



Проверено: anonymous_incognito ()
Последнее исправление: cetjs2 (всего исправлений: 7)
Ответ на: комментарий от northerner

Хайп вокруг Rust сменился ожидаемым разочарованием

И хорошо бы если так - язык будут пользовать те кому он действительно нужен и кто это умеет. Чтоб не как с Ruby, где хорошему языку создали пионерскую инфраструктуру с предсказуемыми последствиями.

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

благодарю

по гитхабу

телепатический модуль только в nightly

MyTrooName ★★★★★
()
Последнее исправление: MyTrooName (всего исправлений: 1)

Чем больше погружаюсь в Rust, тем больше осознаю всю его крутость и то как ущербно программировал на других ЯП

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

Подробности.

Занятно, спасибо. Я так понял что с той статьи еще много всякого с дропами случилось) Я слышал отголоски какие-то про эту историю, но помню что поленился детально разбираться.

я читал, в частности, что порядок деструкторов семантически важен в одной из криптографических библиотек в Расте

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

Но есть изменения, которые тихо меняют семантику кода, не оставляя никаких индикаций что она теперь неправильная

Да, может с дропами и не выйдет починить.

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

Лично я, кстати, в целом согласен что лучше бы ржавчина еще годик-два посидела в ночниках - мне и до 1.0 неплохо жилось, благо поделки у меня мелкие и поломки чинить было просто. Но аргументацию ядровой команды понять тоже вполне могу - мелкие кривости все равно будут - идеального ничего не бывает - а растерять всю энерцию и шансы на коммерческое применение было бы только проще. Это сложный вопрос долгосрочного планирования, я бы не рубил пока так однозначно с плеча что все просрали.

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

Например, деструкторы работают в режиме FIFO, хотя с точки зрения структурной логики это абсурдно, а правильно надо - LIFO - но уже не исправить без поломки обратной совместимости.

Зачем исправлять то, что уже хорошо и понятно работает? Ты явно путаешь раст с плюсами. Например, у тебя есть класс А с полями X и Y (в таком порядке). В плюсах, создавая класс А, ты вызываешь конструктор X, потом Y. Естественно, вызывать деструкторы нужно в обратном порядке - сначала Y, потом X. В расте *нет таких конструкторов*. Ты создаешь Х и Y в любом порядке, после чего создаешь объект А, мувая в него твои X и Y. Создавая А, ты не вызываешь никаких конструкторов и, следовательно, удаляя А, почему должен быть обратный порядок? Раз нет разницы, то прямой порядок куда лучше и понятнее.

PS: Чем мне нравится раст - люди реально думают о языке, а не пихают в него чушь из других ЯП не вникая в суть.

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

почему должен быть обратный порядок?

Для единообразия со сбросами переменных на стеке?

Разный порядок сброса в

let (a, b) = (0.5, 556);

и

let a = 0.5;
let b = 556;

Это не то что бы сильно ожидаемо как по мне.

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

Для единообразия со сбросами переменных на стеке?

struct A(i32);
impl Drop for A { fn drop(&mut self) { println!("{0}", self.0); } }

fn main() {
    let a = A(1);
    let b = A(2);
    let c = a;
}

Тебя не смущает, что код выше выводит 1, потом 2? Ведь мы создали объект A(1), потом A(2) и удалять должны в порядке A(2) и A(1), разве нет? Нет, потому что мув семантика меняет порядок уничтожения объектов. После создания tuple все объекты, перемещенные в него, начинают удаляться согласно правилам tuple.

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

Не смущает, по мне перемещения это отдельный вопрос, а с порядком полей, насколько я успел почитать обсуждений, просто протупили в спешке, а не как-то особенно обдуманно сделали.

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

Где-то широко ухмыльнулся Python.

Какой именно? А то их пачка версий несовместимых, и никто не знает какая из них эталонная. В итоге приходится тупо таскать рантайм (со всратыми батарейками) с собой. Очень удобно.

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

Не смущает, по мне перемещения это отдельный вопрос, а с порядком полей, насколько я успел почитать обсуждений, просто протупили в спешке, а не как-то особенно обдуманно сделали.

let tup = (PrintDrop("x"), PrintDrop("y"), PrintDrop("z"));

Я один вижу создание трех объектов и потом создание тупле с мувом этих объектов внутрь тупле? Раз мув семантика, значит порядок удаления может быть изменен.

А если я напишу

let y = PrintDrop("y");
let tup = (PrintDrop("x"), y, PrintDrop("z"));
то в каком порядке должны вызываться деструкторы? Z-X-Y? Z-Y-X?

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

Я один вижу создание трех объектов и потом создание тупле с мувом этих объектов внутрь тупле?

Нет, я тоже это вижу.

Раз мув семантика, значит порядок удаления может быть изменен.

Да, мне просто не кажется логичным то на что он меняется.

Я все еще не очень понимаю почему ты на семантику перемещения все напираешь.

в каком порядке должны вызываться деструкторы?

В моей картине мира Z-Y-X было бы логичным.

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

В моей картине мира Z-Y-X было бы логичным.

В моей картине мире X-Y-Z более логичный

struct A(i32);
impl Drop for A { fn drop(&mut self) { println!("{0}", self.0); } }

fn main() {
    let a = (A(1), A(2), A(3));
    let b = vec!(A(1), A(2), A(3));
}
Выведет 1-2-3-1-2-3. Не удивлюсь, что удаление массива сложных объектов в прямом порядке быстрее (на современных процессорах), чем удаление в обратном порядке.

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

Вот из-за ... отсутствия стандарта этот язык нафиг никому и не нужен.

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

Черт с ними с альтернативными реализациями, вопрос просто в том что нет четкого описания языка во всех деталях - 100% много мелочей упускаются из виду и на них постепенно все больше кода завязывается. Хорошо хоть все новые RFC пишут сейчас очень подробно, но в целом-то язык не особо детально описан. Вон хотя бы внезапный свежий срач про bool и ffi чего стоит :-( .

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

чтобы использовать половину библиотек - нужен nightly

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

А чтобы использовать nightly - нужен rustup. Мало того что он срет в систему

Это где такое? У меня он только в ~ пишет.

так еще если у тебя Gentoo, то Firefox тянет стабильный, а чтобы кодить нужно rustup. Rustup находит стабильный и не ставится.

Возможно это гентопроблема. В федоре наличие установленных из стандартных репозиториев компилятора и cargo не мешает rustup'у ставить тулчейны.

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

А ты эталонный ССЗБ, как все фанаты пытона. Когда я пишу на C89, я не парюсь каким компилятором это собирать, а на пытоне можно писать только под конкретную версию x.y. Иначе все что сможет твой скрипт - это высирать стектрейсы.

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

Когда я пишу на C89, я не парюсь каким компилятором это собирать

Бабушкам на лавочке расскажешь свои сказки. Ну или ты пишешь исключительно helloworld-ы.

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

Насчет угребищности разношерстного пытона возражений нет? Лол.

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

Планшет на андроиде? Просто в андроид версии стило пока
отсутствует. См. about:support

А вон оно что. Но так 57 на андроиде еще почему то часто валится стал :(

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

Высираешь здесь ты. А твоё хамство выдаёт наглого ламера, так что, независимо от компилятора, твои поделки на С запускать явно не стоит никому.

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

Кстати, даже в самом RFC о стабилизации текущего порядка много раз пишется что он не интуитивный, просто «так уж вышло»:

Это в RFC так написано, а lang team говорит совершенно другое:

While it seems almost everyone would prefer dropping in reverse order if breakage were not an issue, there's still not terribly clear evidence that forward order will cause problems in practice. As has been argued previously on thread, it seems most likely to be a problem for those coming from C++, but there are many differences, some of them subtle, between the two languages, and it's not clear that this one poses special danger.

https://github.com/rust-lang/rfcs/pull/1857#issuecomment-286264016

Кстати, в том же сообщении фанатам reverse-order предлагают поменять его для Vec.

It would be helpful if a proponent of reverse-order drop could make a branch of the compiler where Vec drops in that order. We could then run it through cargobomb, which is capable of running test suites, to get a lower bound on the fallout.

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

я эталонный ССЗБ, когда я пишу на C89

fixed

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

а lang team говорит совершенно другое

Я не вижу там «совершенно другого» - в комменте по ссылке не отридцается странность прямого сбрасывания, там просто говорится что большой трагедии от него не будет. RFC, в общем-то, то же самое говорит.

Кстати, в том же сообщении фанатам reverse-order предлагают поменять его для Vec.

А это к чему процитировано? Я же вообще не спорю что слом направления сброса поломает кучу существующего кода)

Я уже потерялся о чем именно мы спорим)

- Большинство людей ожидают обратный сброс - насколько я вижу это так;

- Прямой сброс не так уж фатален с учетом специфики ржавчины - судя по всему, да.

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

Где-то широко ухмыльнулся Python.

Какой именно? А то их пачка версий несовместимых, и никто не знает какая из них эталонная. В итоге приходится тупо таскать рантайм (со всратыми батарейками) с собой. Очень удобно.

Хлебушек, не тупи. Референсной реализацией Python, заменяющей ему стандарт, является CPython. Любая альтернативная попытка реализации Python (Jython, PyPy, Pyston) проверяется на соответствие возможностям и поведению CPython.

При чем тут версии CPython? Зачем врать, что они несовместимы? В рамках одной мажорной версии код совместим, с оговорками, естественно.

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

Я уже потерялся о чем именно мы спорим)

Изначально тезис звучал так:

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

Я же утверждаю, что нет правильного варианта (для раста). Есть два варианта со своими плюсами и минусами. Выбрали FIFO - ладно. Выбрали бы LIFO - тоже ладно. Проблемы нет на самом деле.

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

Прошу прощения за оффтоп, но где ж вы до сих пор прятались? Раньше я не замечал в растотредах вашего присутствия.

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

Врать нехорошо. Тебе мама с папой разве не говорили?

Есть 2 версии: 2.х и 3.х. Финальная 2.7 во всех дистрибах. 3.х версии развиваются и обратно-совместимы с предыдущими 3.х. Заявлено что 3.х не полностью совместима с 2.х. Не знаю чего тебе там приходится куда таскать и с какими такими батарейками.

PS: какбе во всех новохипстерских язычках вообще статическая линковка. там и рантайм и батарейки и прочая неведомая хренотень.

Q-Master
()

Где срачь по поводу Rust?

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

Референсной реализацией Python, заменяющей ему стандарт, является CPython.

Спека где? Там 2 мажорные версии напрочь несовместимые. И никаких гарантий обратной совместимости внутри ветки кроме «мамай клянус слющай да» от царей скриптухи. Ни один вменяемый разраб не будет полагаться на случайный рантайм в дистре. А у невменозных поделия только срут стектрейсами и падают.

anonymous
()
Ответ на: комментарий от Q-Master

Финальная 2.7 во всех дистрибах.

Ой-вей! Прям таки во всех. Именно 2.7. Ты гарантируешь? И обратную совместимость с лохматыми скриптами из прошлого века тоже? Или ты как бодренький школьник предлагаешь переписывать всё под каждый новый пистон?

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

А ничего, что порядок FIFO или LIFO для одного и того же кода зависит от того, запаниковал этот код или нет? Причем даже не тот дроп что запаниковал, а предыдущие дропы выполняются в разном порядке:

Паники в Z нет, FIFO между X и Y:

fn main() {
    let tup = (PrintDrop("x"), PrintDrop("y"), PrintDrop("z"));
}

Dropping x
Dropping y
Dropping z

Паника в Z, LIFO между X и Y:

fn main() {
    let tup = (PrintDrop("x"), PrintDrop("y"), panic!());
}

Dropping y
Dropping x
gene1
()
Ответ на: комментарий от gene1
fn main() {
    let tup = (PrintDrop("x"), PrintDrop("y"), panic!());
}

Dropping y
Dropping x

Ты не собрал кортеж. Данный код эквивалентен следующему.

let tmp0 = PrintDrop("x");
let tmp1 = PrintDrop("y");
panic!();
anonymous
()
Ответ на: комментарий от anonymous

Технически я понимаю в чем дело.

Но если как разработчик, который пишет код (который может либо запаниковать, либо нет - иногда по причине не зависящей от кода), гораздо легче было бы с одинаковой моделью поведения в обоих случаях. Особенно в деструкторах, чья цель - собрать за собой последствия исполнения кода, в том числе если исполнение было неуспешным.

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

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

Т.е. виноват кортеж, нужно грохать от конца к началу?

Теоретически, вместо создания кортежа тут мог бы быть вызов «конструктора», у которого параметры вообще непонятно в каком порядке, относительно порядка полей в структуре. Как в этом случае обеспечить порядок? А что если созданные структуры попадают в массив и там сортируются?

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

При том, что простой код типа

let v = Vec::new();
for i///....
{
   v.push(MyStruct::new(i))
}
v.sort_by_key(/* ... */);
// делаем что-то
Приведёт к разному порядку вызова деструкторов, в зависимости от того, запаникует до сортировки или после.

Также можно переместить созданный объект внутрь коллекции или структуры, полученной через параметр, в результате объект переживёт своих соседей по времени создания.

Отчасти решить проблему можно, например добавив в каждую структуру невидимое поле «номер создания» (или ведя журнал где-то сбоку), чтоб при уничтожении объектов сначала составлять список под удаление, потом отсортировать его по номеру и вызвать в правильном порядке, но, очевидно, это нахрен никому не надо такой ценой, да и полностью проблему не решит, потому что если сначала полностью разворачивать стек и потом удалять, то порядок будет меняться в зависимости от того, была ли паника и развёртывание кучи стекфреймов или был нормальный выход из функции. Если же сортировать только в пределах одного стекфрейма, то порядок будет меняться в зависимости от того, успел объект до паники попасть в коллекцию из раннего стекфрейма или не успел.

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

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

Причем тут сортировка? Правильно было бы грохать в обратном порядке от конструкции.

Это не проблема кортежей. Так работает семантика перемещения в целом. Вот смотри:

let (a, b) = (PrintDrop("x"), PrintDrop("y"));
if (/* условие */) {
    let c = a;
}
В зависимости от того, сработает ли условие или нет, выведется либо X-Y, либо Y-X. Удаление объектов не привязано к порядку их создания. Объекты удаляются в порядке выхода имен переменных из отвечающей за них областей видимости.

Я не понимаю зачем вы берете какой-то очень частный случай и предлагаете изменить общее правило, потому что оно плохо подходит под этот конкретный единичный случай. Почините одно, проблемы полезут из других щелей. Зачем это надо?

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

А как часто вообще люди пишут код, в котором это имеет значение? Ни разу в плюсах не задумывался, в каком порядке vector вызывает деструкторы. Если попадется контрипример, то ничто не мешает сделать это вручную.

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

А что ты хочешь? В момент паники tup ещё не создан.

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

Ну да. Вот на ML есть стандарт, но это не особо прибавило ему популярности. Есть стандарт на Паскаль, но на стандартном Паскале только на ВМК МГУ учат, от него все плюются, а всё, что сделано хорошего, было сделано на сильно нестандартных версиях. Микрософт забивала и продолжает забивать в своём компиляторе на стандарты СИ++, а Линукс написан с гнутыми расширениями. Интел и Компак расширили стандарт Фортрана в 90-стые, чтобы можно было легче MKL дёргать, и потому интеловский компилятор стал достаточно популярен. У Питона нет стандарта, но на нём активно пишут, а вот стандартный компилятор PL/1 никто так и не сделал полностью, хотя ему много лет.

Вывод тут простой: наличие утверждённого стандарта никак не коррелирует ни с удобством, ни с востребованностью языка.

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

Микрософт забивала и продолжает забивать в своём компиляторе на стандарты СИ++

Да нет, как минимум в последнее время старается следовать, и даже не только С++, но и С. Я читал, что у них просто был очень криво написанный компилятор, что мешало им вносить изменения, в результате они плюнули и переписали его. Еще мне говорили, что когда-то в древних VC6, VC2003 что-то у них со стандартной библиотекой было не так, но то когда было.

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

Вот из-за нестабильности и отсутствия стандарта этот язык нафиг никому и не нужен.

Врёшь, мне нужен.

DarkEld3r ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.