LINUX.ORG.RU

Rust 1.12

 


1

6

Команда разработчиков Rust рада представить релиз Rust 1.12 — системного языка программирования, нацеленного на безопасную работу с памятью, скорость и параллельное выполнение кода. В этот релиз вошёл 1361 патч.

Новое в 1.12

По словам разработчиков, релиз 1.12 является, возможно, самым значительным с момента выпуска релиза 1.0. Самое заметное для пользователей изменение в версии 1.12 — это новый формат ошибок, выдаваемых rustc. Сообществом была проделана многочасовая работа по переводу вывода ошибок на новый формат. Кроме того, для лучшей интеграции и взаимодействия со средой разработки и другим инструментарием ошибки теперь можно выводить в формате JSON при помощи специального флага --error-format=json.

Самое большое внутреннее изменение — это переход на новый формат внутреннего представления программы MIR. Незаметное сегодня, это изменение открывает путь к череде будущих оптимизаций компилятора, и для некоторых кодовых баз оно уже показывает улучшения времени компиляции и уменьшение размера кода. Переход на MIR открывает ранее сложнодоступные возможности анализа и оптимизации. Первое из многочисленных грядущих изменений — переписывание прохода, генерирующего промежуточное представление LLVM, того, что rustc называет «трансляцией». После многомесячных усилий новый бэкенд, основанный на MIR, доказал, что готов к реальной работе. MIR содержит точную информацию о потоке управления программы, поэтому компилятор точно знает, перемещены типы или нет. Это значит, что он статически получает информацию о том, нужно ли выполнять деструктор значения. В случаях, когда значение может быть перемещено или не перемещено в конце области действия, компилятор просто использует флаг из одного бита на стеке, что, в свою очередь, проще для оптимизации проходов в LLVM. Конечный результат — уменьшенный объем работы компилятора и менее раздутый код во время исполнения.

Другие улучшения:

  • Множество мелких улучшений документации.
  • rustc теперь поддерживает три новые цели MUSL на платформе ARM: arm-unknown-linux-musleabi, arm-unknown-linux-musleabihf и armv7-unknown-linux-musleabihf. Эти цели поддерживают статически скомпонованные бинарные файлы. Однако, в собранном виде они пока не распространяются.
  • Повышена читабельность описаний ошибок в ссылках и неизвестных числовых типах.
  • Компилятор теперь может быть собран с LLVM 3.9.
  • Тестовые бинарные файлы теперь поддерживают аргумент --test-threads для указания количества потоков для запуска тестов, который действует точно так же, как переменная окружения RUST_TEST_THREADS.
  • В случае продолжительности выполнения тестов больше минуты показывается предупреждение.
  • Вместе с выпусками Rust теперь доступны пакеты с исходными кодами, которые можно установить при помощи rustup через команду % rustup component add rust-src. Исходные коды могут быть использованы для интеграции и взаимодействия со средой разработки и другим инструментарием.
  • Ускорено обновление индекса реестра.
  • cargo new получил флаг --lib.
  • Добавлен вывод профиля сборки (release/debug) после компиляции.
  • cargo publish получил флаг --dry-run.
  • Сокеты на Linux в подпроцессах теперь закрываются правильно через вызов SOCK_CLOEXEC.
  • Определения Unicode обновлены до 9.0.

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

  • Cell::as_ptr и RefCell::as_ptr.
  • IpAddr, Ivp4Addr и Ipv6Addr получили несколько новых методов.
  • LinkedList и VecDeque теперь имеют новый метод contains.
  • iter::Product и iter::Sum.
  • Option реализует From для содержащегося в нём типа.
  • Cell, RefCell и UnsafeCell реализует From для содержащихся в них типах.
  • Cow<str> реализует FromIterator для char, &str и String.
  • String реализует AddAssign.

Возможности Cargo

Самая большая возможность, добавленная в Cargo в этом цикле — «рабочие области». Описанные в RFC 1525, рабочие области позволяют группе пакетов разделять один общий файл Cargo.lock. Это позволяет намного легче придерживаться единственной версии общих зависимостей при наличии у вас проекта, который делится на несколько пакетов. Для включения этой возможности в большинстве мультипакетных проектов достаточно добавить одну единственную строчку [workspace] в Cargo.toml верхнего уровня, более сложным установкам может потребоваться дополнительная настройка.

Другая существенная возможность — переопределение источника пакета. При помощи инструментов cargo-vendor и cargo-local-registry можно переопределять зависимости локально (vendoring). Со временем это станет фундаментом для построения инфраструктуры зеркал crates.io.

>>> Подробный список изменений

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

★★★★★

Проверено: Falcon-peregrinus ()
Последнее исправление: Falcon-peregrinus (всего исправлений: 10)

Ответ на: комментарий от mersinvald

а где сама туева хуча компилируемых языков-то? Vala, D, Rust, Go... из этих вроде Go более-менее популярный... а что-то менее экзотическое есть? так чтобы на нём реально писали.

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

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

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

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

А чего ты ждал? Что все ломанутся переписывать 30-летнее легаси на Rust и Go просто так, лол?
Ты говорил про крутость си в написании библиотек в плане простоты прикручивания биндингов. Я тебе ответил, что этим преимуществом обладает почти любой из компилируемых языков.
При чем тут кто на чем пишет энтерпрайз?

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

дык «почти любой из туевой кучи». а где куча-то? если в итоге пишут только на C и C++. куча это когда много популярных...

да и 30-летнее легаси-то ладно. но хоть бы новьё какое-то писали. не мешает же никакое легаси в вебе существовать зоопарку всяких руби и питонов и ещё новым появляться

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

«почти любой из туевой кучи». а где куча-то?

То есть ты все таки согласен, что биндинги — не уберфича Си?

если в итоге пишут только на C и C++

Кто?

куча это когда много популярных...

Все, что ты перечислил, включая Rust и Go — популярные языки.

но хоть бы новьё какое-то писали

Таки, внезапно, и пишут.
Или ты ожидаешь, что в условиях нехватки специалистов и библиотек на новых языках, все бросятся писать новые проекты на них?

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

да конечно согласен (хотя... если выбирать из популярных - то хз), правда что в go можно c abi делать, не знал (там прозрачно? а C-шные либы прозрачно можно юзать? без написания биндингов?)

гм. ну крупные/популярные проекты есть на этих языках? на Go видел. на Vala по идее какие-то Gtk'шные проекты должны быть, другое дело что тоже что из этого крупного? на Rust пока только Servo вроде из известного, для него и сделан. а на D? что-то есть вообще?

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

Собственно, в C++ вы можете определить int f(int) в пространствах имен A и B. Если вы сделаете using namespace A и using namespace B одновременно, то не сможете просто вызвать f(0). Вам придется уточнить имя f.

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

Вот представь (просто пример). Вася реализовал Display для String и теперь, тебе в каждом месте использования типа String как Display (println!("{}", string);) прийдётся указывать, что ты хочешь именно реализацию из std...

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

И в первом же абзаце то, о чём я говорю.

The alternative to coherence is to have some way for users to identify which impls are in scope at any time. It has its own complications;

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

Пользуясь случаем, хочу спросить:
Можно ли сделать конверсии с помощью Into, From и As[Mut]Ref автоматическими, наподобии того как работает Deref?

Предположим, я хочу определить свой MyString, обернутый вокруг обычной строки, чтобы реализовать для него какие-то сторонние трейты и получить желаемое поведение.
Но если я так сделаю, каждый раз при передаче MyString в функцию, придется вызывать into(), а при приеме — from().
Почему нельзя это вынести как сахар и при взятии ссылки разворачивтаь в as_ref(), при передаче автоматически подставлять into() и при биндинге с аннотацией типа вызывать from()

Искал RFC или хоть какие-то намеки, но ничего не нашел

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

короче чо-то попиливают, но дикой популярностью не пахнет

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

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

Если обе реализации одновременно введены в область видимости, то никакая.

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

Только если обе одновременно оказались в области видимости.

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

Если я сделал use для Васиного модуля, то да, придется. Если не сделал, то не придется.

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

Если я сделал use для Васиного модуля, то да, придется. Если не сделал, то не придется.

Речь идёт не о модуле, а о реализации трейта. Если подключать трейты по use mod;, то я считаю это не правильно, т.к. любая реализация трейта может привести к необходимости правки всех мест где возникают конфликты, то есть я написал impl Display for String и поломал все модули которые используют мой модуль. Если ты хочешь использовать String как Display, то откуда компилятору знать, какой Display использовать? С когерентной системой типов такой проблемы нет, ты просто указываешь use Trait;, но с множественной реализацией так не работает, необходимо указать именно конкретную реализацию.

Если обе реализации одновременно введены в область видимости, то никакая.

Только если обе одновременно оказались в области видимости.

То есть реализация по-умолчанию отсутствует и необходимо явное use impl_T_for_S; для каждой реализации? То есть в каждом крейте у нас будет свой prelude, который надо будет подключать в каждом модуле для использования реализаций трейтов для типов крейта.

use a::{S, Clone_for_S, Display_for_S, Debug_for_S, etc};

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

Перечитайте, пожалуйста, то, что я вам отвечал. Там все описано.

Нет, это вы перечитайте всю ветку, а то каждый ответ как лепет глухонемого.

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

Только если обе одновременно оказались в области видимости.

То есть реализация по-умолчанию отсутствует и необходимо явное use impl_T_for_S; для каждой реализации?

Вы сами-то можете объяснить, что вам в сказанном не понятно и почему из сказанного вы делаете такие странные выводы?

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

Вы сами-то можете объяснить, что вам в сказанном не понятно и почему из сказанного вы делаете такие странные выводы?

Как ты будешь вводить реализацию в область видимости?

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

Как ты будешь вводить реализацию в область видимости?

Это не ответ на мой вопрос. Но попробую еще раз.

Есть тип S. Есть трейт T. Есть модуль Vasya с реализацией T для S. Есть модуль Kolya с другой реализацией T для S.

Если я делаю только use Vasya, то вижу только одну реализацию T для S. Она и используется по умолчанию.

Если я делаю только use Kolya, то вижу только одну реализацию T.

Только если я делаю и use Vasya, и use Kolya, то тогда при попытке задействовать T для S возникает неоднозначность, на которую должен указать компилятор.

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

Это не ответ на мой вопрос. Но попробую еще раз.

Два чая этому господину.

Только если я делаю и use Vasya, и use Kolya, то тогда при попытке задействовать T для S возникает неоднозначность, на которую должен указать компилятор.

Так это то, о чём я и говорил.

любая реализация трейта может привести к необходимости правки всех мест где возникают конфликты, то есть я написал impl Display for String и поломал все модули которые используют мой модуль.

Мне продолжить объяснять на сколько это глупый подход?

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

Мне продолжить объяснять на сколько это глупый подход?

Почему-то вам кажется, что я не понял вашу точку зрения. Однако, я ее давно понял. Просто не считаю ее правильной.

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

Однако, я ее давно понял.

Однако ранее:

Перечитайте, пожалуйста, то, что я вам отвечал. Там все описано.

----

Просто не считаю ее правильной.

=/

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

С предложенной тобой моделью, любая, Карл, реализация трейта может поломать код в любом месте.

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

В общем, где грань проходит? (:

Лучше сделать

#define private public

#include «нечто.h»

И дальше лезь куда хочешь.

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

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

Или вам так кажется.

eao197 ★★★★★
()

До появления более менее вменяемого наследования(хотябы как в go) rust не сможет заменть c++. А какой тогда от него толк? Обменять теоретическую стабильность кода на замедление написания кода? Когда начнут делать rust++?

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

Опять 25...

Очевидно, что проблема непонята. Мне то же. Сильное ощущение, что вы видите то, что другие увидеть не могут. Как называются такие люди с воображаемыми друзьями вы знаете?

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

Когда начнут делать rust++?

Когда концепты в С++ появятся, то есть в районе 2025.

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

Товарищ выше предлагает такую концепцию.

// crate t
trait T {
    fn foo(&self) {}
}

// crate s
struct S {}

// crate a
impl t::T for s::S {}

// crate b
impl t::T for s::S {}

// crate c
use a; // неявное использование реализации T

(S {}).foo();

// crate d
use a; // неявное использование реализации T
use b; // неявное использование реализации T, конфликт
use a::T for s::S; // явное использование T из a

(S {}).foo();

Я ему говорю, что реализация любого трейта может вызвать такой конфликт, что означает явное указание реализации. Если кто-то реализует в crate b trait T for S, это может поломать любой др. код, который использует неявное T for S из др. места.

К примеру. Я реализовал Display для String, это будет означать явное указание use std::fmt::Display (или my::Display) for std::string::String в каждом месте, где используется мой код.

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

Если кто-то реализует в crate b trait T for S, это может поломать любой др. код

Вот это непонятно. Почему любой, а не только тот который попробует использовать b?

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

Вот это непонятно. Почему любой, а не только тот который попробует использовать b?

Я это и имею в виду.

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

Я это и имею в виду.

Похоже ваш друг и в самом деле воображаемый. :)

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

Что, имхо, превращает эту воображаемую фичу в пшик.

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

Тем не менее, фича всё-таки есть: можно создавать свои трейты и реализовывать их для «чужих» типов или наоборот. И в большинстве случаев этого должно хватать.

Впрочем, доступа к приватным данным всё равно не будет.

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

Почему любой, а не только тот который попробует использовать b?

Вот я тоже не понял, почему аноним говорит про поломку любого кода.

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

Ну я не спешу. Тестировал на 1.14, если вдруг на 3.21 это станет критическим багом, то можно будет неплохо заработать шантажируя слить в паблик. Годный план, согласен?

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

Это не одно и тоже, что прилепить новый интерфейс к тому же самому объекту.

Ну давай ещё раз. Есть либа с интерфейсом «ползти» и типом «улитка». И в С++ и в расте к приватным данным обратиться будет нельзя. Как по мне, инкапсуляция не нарушается, но идём дальше.

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

Передать летающую_улитку по базовому интерфейсу в С++ можно, но если та сторона ничего не знает, то ничего не случится. Аналогично в расте - трейт надо импортировать явно. И, как по мне, это ничем не отличается от явного использования функции типа fly(Snail&) в С++. Ну или создания обёртки и использования её методов. Или динамик каста к нужному интерфейсу, раз уж мы о нём знаем.

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

Вася реализовал Display для String и теперь, тебе в каждом месте использования типа String как Display (println!(«{}», string);) прийдётся указывать, что ты хочешь именно реализацию из std...

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

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

Мне продолжить объяснять на сколько это глупый подход?

Попробуй объяснить мне.

то есть я написал impl Display for String и поломал все модули которые используют мой модуль.

Почему? Ведь реализации (кроме «дефолтных» из prelude) надо каждый раз явно импортировать. То есть, у тебя будет использоваться своя реализация Display для строк, но у тех, кто использует твою либу, если они явно не захотели твою реализацию, будет использоваться дефолтная.

Или в чём проблема?

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

И дальше лезь куда хочешь.

Справедливости ради, это UB (в общем случае).

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

Годный план, согласен?

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

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

Да тут же только нищеброды тусуются. Думаешь через пару лет типичный rust'овщик таки начнет хоть сколь-нибудь зарабатывать?

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

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

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

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

Почему? Ведь реализации (кроме «дефолтных» из prelude) надо каждый раз явно импортировать. То есть, у тебя будет использоваться своя реализация Display для строк, но у тех, кто использует твою либу, если они явно не захотели твою реализацию, будет использоваться дефолтная.

Вот и я о том же, что нужно как-то идентифицировать реализации в такой модели, но тот что выше, говорит о неявном использовании при использовании модуля, а не импорте реализации (как я предлагал выше).

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

а не импорте реализации (как я предлагал выше).

Ну то есть, по идее, можно сделать беспроблемный вариант, так? Просто может я что-то «более глобальное» упускаю.

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

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

Зачем у тебя main в lib.rs ?

https://rurust.github.io/rust_book_ru/src/crates-and-modules.html

«Так как в этом контейнере нет функции main(), и называется он lib.rs, Cargo соберет этот контейнер в виде библиотеки.»

Cargo считает lib.rs за корень контейнера.

Твои проблемы, это не проблемы rustc или даже cargo. Это твои личные проблемы. А ты, жадный школьник, ещё и бабки хочешь заработать на своих кривых ручках. Сходи на reddit и посмеши народ в /r/rust

WatchCat ★★★★★
()
Последнее исправление: WatchCat (всего исправлений: 1)
17 ноября 2016 г.
Ответ на: комментарий от WatchCat

Митап по Rust в Kaspersky Lab

Уважаемые участники форума, каждый месяц мы в «Лаборатории Касперского» проводим встречи CoLaboratory, на которых технические специалисты с различными интересами могут встретиться и поговорить с экспертами. Встреча 22 ноября будет посвящена Rust — приходите! https://events.kaspersky.com/event/rust2

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