Rust 1.13 Release

    The Rust team is pleased to announce the release of Rust 1.13.0. Rust is a system programming language aimed at security, speed and parallel code execution.


    As usual, you can install Rust 1.13.0 from the corresponding page on the official website, as well as familiarize yourself with a detailed list of changes in 1.13.0 on GitHub. This release includes 1,448 patches.


    It was a really hot time in Rust. We participated in three consecutive conferences - RustConf , RustFest and Rust Belt Rust . It was great to see so many Rust lovers; we met many for the first time! We thought a lot about the future, developed a plan for 2017 and created the tools that our users needed .


    And despite all this, we put together a new release with a bunch of cool new features.


    What is included in the stable version 1.13


    Release 1.13 includes the long-awaited operator ?, faster compilation, the addition of
    some features to Cargo and the standard library. This release also brings many small improvements to the documentation and error messages. This is the result of the work of many people, and they are not mentioned individually in the release notes.


    The release contains important vulnerability fixes in Cargo. It depends on curl and OpenSSL,
    and they both recently posted security updates. For more details see the corresponding announcements curl 7.51.0 and OpenSSL 1.0.2j .


    Operator ?


    Rust has acquired a new operator ?. It makes work with errors much nicer,
    removing visual noise. For example, we have code to read data from a file:


    fn read_username_from_file() -> Result {
        let f = File::open("username.txt");
        let mut f = match f {
            Ok(file) => file,
            Err(e) => return Err(e),
        };
        let mut s = String::new();
        match f.read_to_string(&mut s) {
            Ok(_) => Ok(s),
            Err(e) => Err(e),
        }
    }

    The code contains two paths that may result in an error: opening the file and reading data from it. If one of them crashes, we need to return an error from the function read_username_from_file. To do this, we have to get the matchresult of I / O operations. However, here we are simply throwing an error over the call stack, and usage matchis a constantly repeating boilerplate code. Its hard to read.


    From the ?above code would look like this:


    fn read_username_from_file() -> Result {
        let mut f = File::open("username.txt")?;
        let mut s = String::new();
        f.read_to_string(&mut s)?;
        Ok(s)
    }

    ?is an abbreviation for the whole expression matchthat we wrote above. In other words, it ?takes Resultand, if it does Ok, expands it and gives the embedded value. If the value Resultis - Err, ?returns control from the current function. It is much easier to read: instead of the whole expression we use the symbol "?". So we show that we handle the error in a standard way, passing it up the stack.


    Experienced programmers Rust will note that this is the same as that of the macro try!,
    available even with Rust 1.0. Indeed, it is the same. Until 1.13 it read_username_from_filecould be implemented like this:


    fn read_username_from_file() -> Result {
        let mut f = try!(File::open("username.txt"));
        let mut s = String::new();
        try!(f.read_to_string(&mut s));
        Ok(s)
    }

    So why add extensions to the language if we already have a macro? For different reasons.
    Firstly, it has try!proven its exceptional usefulness and is often used in idiomatic Rust. It is used so often that it deserves a sweet syntax. This kind of evolution is one of the big advantages of a powerful macro system: the proposed language syntax extensions can be prototyped and tested without changing the language itself. In turn, a macro that has become extremely useful may indicate a lack of language capabilities. This evolution from try!to ?is a great example.


    One of the reasons why it try!needs to be sugared is that it is pretty ugly in case of multiple calls in the chain. Compare:


    try!(try!(try!(foo()).bar()).baz())

    a counterweight:


    foo()?.bar()?.baz()?

    The first fragment is quite difficult to read, and each error handling layer attributes a
    call to the beginning of the expression try!. This requires an excessive concentration of attention for the trivial forwarding of errors, and overshadows the main working code - calls foo, barand baz. This type of call hooking with error handling is typical for situations like a design pattern builder.


    Finally, specialized syntax will make it easier to report errors - we can account for usage ?. And for code from macros it's hard to make good mistakes. However, in this release, usage error messages ?are not yet fully implemented.


    Although this is a small improvement, in our experience it ?is a worthy improvement in ergonomics try!. This is a good example of the consistent improvement in the quality of life that Rust will continue to receive.


    For more information about ?, refer to RFC 243 .


    Performance improvement


    We seriously focused on compiler performance. We already have some good news, but in future releases it will be even better.


    Mark Simulacrum and Nick Cameron have honed perf.rust-lang.org , our compiler performance tracking tool. He regularly runs rustc-benchmarks on dedicated hardware and tracks changes over time. This tool records the results of each compilation step and is used by developers to narrow down the search range for commits that lead to performance degradation. This is an important part of our toolkit!


    We can use it to take a look at the performance graph during the 1.13 development period - from August 16 to September 29 (the graph is shown below). The schedule starts on August 25 and is filtered according to several criteria - to exclude unreliable, incomplete or conflicting results. You can notice large reductions that are quantified on the corresponding statistics page .



    Performance graph



    September 1, there was a significant improvement - Niko turned on normalized cache projections during translation . This means that during LLVM IR generation, the compiler no longer recounts specific instances of associated types at each place they are used. Now it reuses previously calculated values. This optimization does not affect any code, but when certain typical fragments are encountered, you will notice the difference. For example, for futures-rs , the build time of the debug version improved by 40% .


    Another similar optimization is implemented by Michael Woerister. It speeds up the compilation of containers that export many inline functions. If the function is marked as #[inline], the compiler saves its representation in MIR in rlib - in addition to the usual translation for use in the current container. Then he translates it in each container that calls this function. In retrospect, Michael made an obvious optimization: in some cases, inline functions are only for other containers, so the compiler does not have to translate them in the container where they are declared. Of course, except when they are called there. This saves time on converting a function to LLVM IR and processing it LLVM: optimization and code generation.


    In some cases, this gives impressive results. Ndarray build time improved by 50% , and for (unpublished) winapi 0.3 , rustc no longer produces native code at all.


    But wait, that's not all! Nick Nethercote also turned his attention to compiler performance , focusing on profiling and microoptimizations. This release already includes some of the fruits of his labors , others are scheduled for 1.14.


    See the release notes for more details .


    Other notable changes


    The release contains important vulnerability fixes in Cargo. It depends on curl and OpenSSL, and they both recently posted security updates. For more details see the corresponding announcements curl 7.51.0 and OpenSSL 1.0.2j .


    Now you can use macros in place of type ( RFC 873 ) and apply attributes to statements ( RFC 16 ):


    // Используем макрос, чтобы назвать тип
    macro_rules! Tuple {
        { $A:ty,$B:ty } => { ($A, $B) }
    }
    let x: Tuple!(i32, i32) = (1, 2);

    // Применяем атрибут статического анализа к единственному оператору
    #[allow(uppercase_variable)]
    let BAD_STYLE = List::new();

    Built-in reset flags ( English inline drop flags) are removed. Previously, the compiler stored a "reset flag" in structures in order to understand whether to execute a destructor when structures moved in some execution paths. This increased the size of the structures, which prevented the transfer of types with destructors across the FFI border. For code that does not move structures only in terms of execution paths, this memory was wasted. In 1.12, MIR became the default translator - this was the foundation of many improvements, including the removal of these built-in reset flags . Now the reset flags are on the stack of those functions that need them.


    In 1.13 there is a serious bug in code generation for ARM with hardware implementation of floating point numbers. These are most ARM-based platforms. ARM is currently a support level 2 platform, so this bug does not block the release. Since 1.13 contains a security patch, we recommend that ARM users use 1.14 beta. This thread will receive a fix for this issue soon.


    Stabilization of language features



    Library stabilization



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



    Подробнее смотрите замечания к выпуску.


    Разработчики версии 1.13.0


    155 человек внесли свой вклад в 1.13.0. Большое вам спасибо!


    Список участников
    • Aaron Gallagher
    • Abhishek Kumar
    • aclarry
    • Adam Medziński
    • Ahmed Charles
    • Aleksey Kladov
    • Alexander von Gluck IV
    • Alexandre Oliveira
    • Alex Burka
    • Alex Crichton
    • Amanieu d'Antras
    • Amit Levy
    • Andrea Corradi
    • Andre Bogus
    • Andrew Cann
    • Andrew Cantino
    • Andrew Lygin
    • Andrew Paseltiner
    • Andy Russell
    • Ariel Ben-Yehuda
    • arthurprs
    • Ashley Williams
    • athulappadan
    • Austin Hicks
    • bors
    • Brian Anderson
    • c4rlo
    • Caleb Jones
    • CensoredUsername
    • cgswords
    • changchun.fan
    • Chiu-Hsiang Hsu
    • Chris Stankus
    • Christopher Serr
    • Chris Wong
    • clementmiao
    • Cobrand
    • Corey Farwell
    • Cristi Cobzarenco
    • crypto-universe
    • dangcheng
    • Daniele Baracchi
    • DarkEld3r
    • David Tolnay
    • Dustin Bensing
    • Eduard Burtescu
    • Eduard-Mihai Burtescu
    • Eitan Adler
    • Erik Uggeldahl
    • Esteban Küber
    • Eugene Bulkin
    • Eugene R Gonzalez
    • Fabian Zaiser
    • Federico Ravasio
    • Felix S. Klock II
    • Florian Gilcher
    • Gavin Baker
    • Georg Brandl
    • ggomez
    • Gianni Ciccarelli
    • Guillaume Gomez
    • Jacob
    • jacobpadkins
    • Jake Goldsborough
    • Jake Goulding
    • Jakob Demler
    • James Duley
    • James Miller
    • Jared Roesch
    • Jared Wyles
    • Jeffrey Seyfried
    • JessRudder
    • Joe Neeman
    • Johannes Löthberg
    • John Firebaugh
    • johnthagen
    • Jonas Schievink
    • Jonathan Turner
    • Jorge Aparicio
    • Joseph Dunne
    • Josh Triplett
    • Justin LeFebvre
    • Keegan McAllister
    • Keith Yeung
    • Keunhong Lee
    • king6cong
    • Knight
    • knight42
    • Kylo Ginsberg
    • Liigo
    • Manish Goregaokar
    • Mark-Simulacrum
    • Matthew Piziak
    • Matt Ickstadt
    • mcarton
    • Michael Layne
    • Michael Woerister
    • Mikhail Modin
    • Mohit Agarwal
    • Nazım Can Altınova
    • Neil Williams
    • Nicholas Nethercote
    • Nick Cameron
    • Nick Platt
    • Niels Sascha Reedijk
    • Nikita Baksalyar
    • Niko Matsakis
    • Oliver Middleton
    • Oliver Schneider
    • orbea
    • Panashe M. Fundira
    • Patrick Walton
    • Paul fanelli
    • philipp
    • Phil ruffwind
    • Piotr jawniak
    • pliniker
    • Quietmisdreavus
    • Rahul sharma
    • Richard Janis Goldschmidt
    • Scott A Carr
    • Scott Olson
    • Sean mcthur
    • Sebastian ullrich
    • Sebastien marie
    • Seo sanghyeon
    • Sergio benitez
    • Shyam sundar b
    • silenuss
    • Simonas kazlauskas
    • Simon sapin
    • Srinivas Reddy Thatiparthy
    • Stefan schindler
    • Stephan hügel
    • Steve klabnik
    • Steven allen
    • Steven fackler
    • Terry sun
    • Thomas garcia
    • Tim neumann
    • Tobias Bucher
    • Tomasz Miąsko
    • trixnz
    • Tshepang Lekhonkhobe
    • Ulrich weigand
    • Ulrik Sverdrup
    • Vadim chugunov
    • Vadim petrochenkov
    • Vanja cosic
    • Vincent escape
    • Wesley wiser
    • William Lee
    • Ximin luo
    • Yossi konstantinovsky
    • zjhmale

    Also popular now: