
Rust 1.26 released - dikiaap
https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
======
kibwen
So yeah, 1.26 is the most substantial release since 1.0, but there's lots more
goodies coming in the pipeline. :) It just so happened that all the
initiatives from last year are preparing to land at approximately the same
time. For example, coming up next in 1.27 is stable SIMD:
[https://github.com/rust-lang/rust/pull/49664](https://github.com/rust-
lang/rust/pull/49664) (though only for x86/x86_64 at first; more platforms and
high-level crossplatform APIs are on the way).

~~~
pimeys
The features I'm highly expecting are pinned references and async/await, that
will make most of my paid Rust to be so much more readable and maintainable. I
know these are coming this year, but any chance they might be already in 1.27?

1.26 has impl Trait, which is one of those things that really makes your life
easier as a Rust developer. I've been using beta already with the new API I'm
building just to get that feature, now on stable right before I'm actually
thinking of deploying the API. Nice.

~~~
kibwen
The RFC for async/await was actually just accepted two days ago!
[https://github.com/rust-
lang/rfcs/pull/2394#issuecomment-387...](https://github.com/rust-
lang/rfcs/pull/2394#issuecomment-387550523) :) It's a priority for this year,
but it'll be a few months yet; unless something goes unexpectedly wrong, I'd
expect it no later than 1.30, releasing on October 25th.

------
dikaiosune
I recently found myself inserting &/*/ref/ref mut into match expressions
before I'd even seen a compiler error. My first thought was "aha, look at how
experienced I am with Rust now!" Followed immediately by "I can't wait until
this isn't something you have to learn to be productive with the language."
And now that day has come! Really exciting for me.

I also need to go and find all of my impl Trait TODO comments and get to work
on cleaning those up! What a good day.

I should also say that while I haven't read the second edition of the book yet
I am excited to have some new Rust-related content to read. The first edition
of the book was a really eye-opening learning experience for me (both about
computers and Rust and also about how to build a community and prioritize
teaching) and I can only imagine what an improvement on that is like.

~~~
eyko
Nicer `match` bindings was easily my favourite feature of this announcement. I
can't recall the number of times I've been trying to show some rust code to
someone and then pattern matching comes in and I get a cold drip of sweat
expecting their reaction/questions as to why do we need to be so verbose.
Happy day for me as well indeed!

------
steveklabnik
So, so, so much stuff in this release! The next few are shaping up to be
similar. Very exciting times!

As always, happy to answer questions, provide context, etc.

~~~
squiguy7
In this example:

    
    
      fn foo(x: i32) -> Box<Iterator<Item = i32>> {
          let iter = vec![1, 2, 3]
              .into_iter()
              .map(|x| x + 1);
    
          if x % 2 == 0 {
              Box::new(iter.filter(|x| x % 2 == 0))
          } else {
              Box::new(iter)
          }
      }
    

Why is it that I can't return `impl Iterator<Item = i32>`? Doesn't the
`Filter` type implement `Iterator` for the same associated type?

~~~
wcrichton
The guarantee of `impl Trait` is that if I want to call a trait method on the
returned object, e.g. for iterators if I want to call `foo(0).next()`, then
the function pointer will always be in the same place on the object in memory
(static dispatch).

By contrast, if I returned a boxed trait, then calling the trait method
requires a dynamic lookup to find the method on the boxed object, and then
jumping to that function (dynamic dispatch). In this example, `iter.map(..)`
and `iter.filter(..)` return two different implementations of the Iterator
trait, so dynamic dispatch is required.

In general, if your function returns multiple possible implementations of a
given trait, then the compiler cannot know where the trait methods will be
statically, so it is impossible to do static dispatch. Since impl Trait wants
to guarantee static dispatch, it requires that only one possible
implementation of the trait be returned.

~~~
naasking
I think your explanation of static and dynamic dispatch is either wrong, or
incredibly confusing.

The offset of the function pointers is always statically known for a given
trait/interface type, it's just the actual vtable instance that may not be
known, ie. the concrete type implementing that trait/interface. A statically
known vtable instance that can be inlined/monomorphized is static dispatch,
and if it's not known at compile-time it must be dynamically dispatched.

~~~
burntsushi
I don't understand what's so confusing about it. GP says

"calling the trait method requires a dynamic lookup to find the method on the
boxed object"

It sounds like all you want to say is

"calling the trait method requires a dynamic lookup to find [the vtable
instance, which is then used to find] the method on the boxed object"

~~~
naasking
That's not the clarification I was making. For instance, I simply can't
interpret this line from the original post as anything but incorrect:

> then the function pointer will always be in the same place on the object in
> memory (static dispatch)

As I said, static vs. dynamic dispatch is about knowledge of the vtable
instance, not about the offset into the object or the vtable. All of the
offsets are always known statically, it's merely what you're indexing _into_
that may or may not be known statically.

Maybe I'm being pedantic, but I've found that there's a lot of
misunderstanding surrounding static vs. dynamic dispatch.

~~~
burntsushi
I see. Makes sense. It might help to show what the representation in memory of
a trait object is. (I'm assuming there's a type for it somewhere in rustc, but
I don't know where offhand.)

~~~
steveklabnik
[https://doc.rust-
lang.org/stable/std/raw/struct.TraitObject....](https://doc.rust-
lang.org/stable/std/raw/struct.TraitObject.html)

------
runevault
Everyone keeps talking about impl Trait (which is great) but I'm super pumped
for ? working in main now. Was recently writing some code as I finally got
back to rust and forgot about that edge and had to write a match block when ?
would have been good enough (felt silly to make a method just to handle that).

~~~
kibwen
Agreed, being able to get rid of spurious unwraps in trivial code and small
code examples and replace them with idiomatic error handling is lovely. :)

------
pcx
The wonderful thing about Rust is that despite being fairly new and rare to
get paid for working on it, it is still enticing( to most programmers I've
met). The consistent effort to improve it is really paying off. I hope it gets
to a place where it's `batteries included` like Python. There are some glaring
holes in the stdlib I would like to see fixed sometime soon.

~~~
saghm
The argument for putting things in third-party "blessed" crates rather than
the standard library is that it allows them not to have to follow the
versioning guarantees of Rust itself. Given that the core team has stated that
they don't plan to have a Rust 2.0, this means that there wouldn't _ever_ be
any API-breaking changes for things added to the standard library; by having
things like `regex` and `rand` be external crates, versions bumps can happen
independently happen, which means (among other things) that major version
bumps are possible.

~~~
pcx
That's certainly an advantage. But for devs like me, we are used to prog langs
providing a set of APIs in the stdlibs, that are officially blessed to be
maintained. They might not be the best designed, but they are guaranteed to
work for a long long time. This kind of trust is very hard to build for 3rd
part libs. It's a trade-off to make, and rust for now has decided to keep
stdlib lean and quick to iterate over. But I hope at some point, Rust devs
would consider including more APIs.

~~~
saghm
I think that the rust-lang-nursery Github organization[1] is designed to solve
part of the trust issue. A lot of the "batteries" crates are in there; `rand`,
`futures`, `error-chain`, `lazy-static`, `glob`, `bitflags`, and `log` catch
my eye after looking through. In the long run, I don't think that having
things like the blessed HTTP library being third-party will be that much of a
detriment; at least when I was writing Python, almost everyone I knew used the
`requests` library, and nobody worried about it not being part of the standard
library.

------
ovao
The post doesn’t go into much detail about how the new i128 and u128 types are
implemented, so for anyone who’s as curious as I was, the RFC is here:
[https://github.com/rust-
lang/rfcs/blob/master/text/1504-int1...](https://github.com/rust-
lang/rfcs/blob/master/text/1504-int128.md)

------
cjcole
"Speaking of print, you can pre-order a dead tree version of the book from
NoStarch Press. The contents are identical, but you get a nice physical book
to put on a shelf, or a beautifully typeset PDF. Proceeds are going to
charity."

Which charity/charities?

~~~
steveklabnik
Black Girls Code is the intention today, but originally it was going to be a
different tech charity that is no longer around, OpenHatch.

~~~
cozicoolmail
Black Girls Code, in my opinion, is a great organization with a well executed
mission and good reach (several major cities throughout the US). Glad Rust
picked them.

Source: I've volunteered for them in the past as an instructor.

~~~
steveklabnik
I have only heard wonderful things; I'm glad your experience is consistent :)

I have no idea how _big_ the donations will be, but we're giving it a shot!

------
GolDDranks
There's so much long-awaited features that are finally stabilised.

impl Trait is HUGE. And there's tons of other stuff too. This must be the
biggest single release since 1.0.

------
bpicolo
> Inclusive ranges are especially useful if you want to iterate over every
> possible value in a range

Out of curiosity, why was the (or an alternative) choice not to make the
compiler understand that the 0..256 was not inclusive, and somehow correct the
literal value to do what's intended? Would that have been unusually
complicated or?

Edit: Overall, still an amazing release, this was just the bit I'm curious
about :) Great work by the whole Rust team/community

~~~
steveklabnik
Every language I’m aware of has different syntax for inclusive vs exclusive
range; making it situational would be quite confusing, I’d imagine.

~~~
Animats
Go deliberately left that out.[1] Probably a good decision.

[1] [https://groups.google.com/forum/#!msg/golang-
nuts/7J8FY07dkW...](https://groups.google.com/forum/#!msg/golang-
nuts/7J8FY07dkW0/goWaNVOkQU0J)

~~~
pjmlp
Go left almost everything out.

------
hardwaresofton
As a person who started writing rust this last week, I think I might have
picked the best possible time to get in on it.

The community is amazing, and I actually understand all these features that
were released I've run into about half of the issues they fix already.

Rust is coming along very very nicely.

~~~
MuffinFlavored
what else would you say it is missing?

~~~
hardwaresofton
Unfortunately I don't have a good full response to this (otherwise I could
contribute it and actually help), but off-head I was surprised by the lack of
a `cargo install` ([https://github.com/rust-
lang/cargo/issues/2179](https://github.com/rust-lang/cargo/issues/2179)). A
few minutes later though I was used to googling for the package i wanted, and
getting the version I wanted to use and adding it to Cargo.toml, and that's
arguably a better way to do things to start with.

I haven't used it enough to have much more to say -- I've found everything
pretty ergonomic so far (especially for a C/C++-tier language), I was most
frequently confused when thinking of the most idiomatic way of doing
something, but that's remedied by reading more (the rust book first/second
edition, the rust cookbook). This should change over the coming weeks.

This isn't a particularly useful comment, but I chose Rust over Common Lisp
recently for this new project, and I've found the std library's google-ability
to be excellent for rust -- very few pages about steel have come up so far
("result rust" in DDG brings up rustlang related links). When I explored CL, I
did not find that to be the case, but maybe I just didn't know where to look
-- hyperspec is close but it is a terrible document to navigate through, and
the 90s graphics didn't help (though they were nostalgic). Rust documentation
is very often concise, well structured, and passably beautiful. I was also
pleased with the Abstract Data Type solution in rust -- tagged unions. Some
code:

    
    
        #[derive(Debug)]
        pub enum ConfigLoadError {
            EmptyFilePath,
            IO(IOError),
            TomlParse(TomlError)
        }
    

The abstraction enabled here is just right for me, super similar to code that
I'd write in Haskell, and helps me abstract over errors thrown by utility
libraries (in this case `toml-rs`).

~~~
red75prime
You may want to see the failure crate. In my practice most errors cannot be
handled by a program and the only sensible thing to do is to pass an error
description to a user or a programmer. Such fine-grained error type
information as in your example is rarely useful. The failure crate provides a
way to create detailed error descriptions (see `Context`) and fixes
shortcomings of the standard Error trait.

------
sushisource
Super excited to see how much better my code will look with impl Trait and the
"no need for &/ref in pattern matches" stuff.

Keep it up Rust team. The language is incredible! Really my only daily
complaint is IDE support is still abysmally slow, in both IntelliJ and VSCode.

------
vvanders
So freaking excited about impl trait.

This and not being able to do paramterized array sizes for things like SoA,
AoSoA where the two things that I feel like were missing from Rust. Really
happy to see the first landing(and I understand work is going on for the
second).

~~~
steveklabnik
There was some sort of SoA derive going around, I thought. Regardless, you’re
right; we’re hoping const generics lands in nightly this year and stabilizes
early next year.

------
mathw
I wrote a program yesterday in 1.25 which did some simple file I/O right there
in main, didn't need to be fancy at all... and then this morning I come online
and find that we now have fs::read_to_string and main can return a Result...
great!

But I needed this yesterday!

Seriously though, this is an amazing release and so much stuff in here I've
been looking forward to for ages. impl Trait is going to change the way I
write Rust.

------
ben0x539
Hooray, congrats to the rust contributors, once again. :)

Personally, not a fan of the match change. But then I was already not a fan of
autoderef in method calls.

~~~
bluejekyll
The biggest negative I've seen is this:

    
    
        let example: (String, String, String) = ("ref".to_string(), "to".to_string(), "ref".to_string());
       
        let example: (&str, &str, &str) = match &example {
           (ref1, to, ref2) => (ref1, to, ref2),
        };
    
    

Which might look confusing to people, it's converting from &(1,2) to
(&1,&2)... but it's still type safe. Besides something like this, is there
another reason to be worried about it?

[https://play.rust-
lang.org/?gist=e37f9b31cc5e5c7b9d19c6b0a4c...](https://play.rust-
lang.org/?gist=e37f9b31cc5e5c7b9d19c6b0a4c44441&version=stable&mode=debug)

~~~
ben0x539
Reading (or even writing!) rust code, you can get increasingly far without
knowing what level of indirection you're operating on. I don't enjoy that. I
don't personally feel like the notational burden for explicitness is enormous.

For field access/method calls, autoderef is a bigger convenience because we
don't have the C++ -> operator, but I think I'd have preferred a syntax change
here over the current behavior.

~~~
Rusky
The match changes here don't bother me anywhere near as much as deref
coercions do, because they _preserve_ the level of indirection.

Deref coercion makes a &Box<T> behave like a &T (removing a level of
indirection). Default binding modes only make a &(T, U) behave like a (&T,
&U).

I've idly wondered whether it would have been possible to replace deref
coercions with something like this. Making Box<T> behave like &T kinda works
but loses you the ability to control `&T` vs `&mut T`, but maybe `x.y` where
`x: &T` could "pass the reference on" giving you a `&U`.

------
jmhain
Is it possible to match the end of a slice with slice patterns? Something
like:

    
    
        fn foo(s: &[char]) {
            match s {
                ['a', 'b'] => (),
                [.. 'b', 'c'] => (),
                _ => (),
            }
        }

~~~
steveklabnik
Not today, but it's coming. This kind of thing does work on nightly.

~~~
Lev1a
I was mostly excited about slice patterns because of a pattern I wanted to be
able to write:

    
    
        some_collection.windows(2).filter(|[a,b]|a==b).map(|[a, _] |a).collect();
    

Turns out the compiler rejects that with a "refutable pattern" error, because
the args part of the filter/map closures do not handle the situation where the
slice could be empty, which AFAIK can not occur when using windows/chunks/...

Maybe there has to be some special case handling for this pattern to be valid?

~~~
steveklabnik
Hm, interesting. I think this isn't possible without integer generics.

~~~
Lev1a
Because the pattern in the filter closure would have to be generic over the
length or am I mistaken?

------
_zachs
I'm super excited about the "Basic slice patterns". I've been learning some
Elixir at the same time and was blown away by the different style of
programming you can write in using matching. Glad to be able to try it out in
Rust as well.

------
kccqzy
Existential types are great! Although I must mention that existential types
are basically the way to model OO-style information hiding. It's a great tool
to have in any mature type system, although I do wonder how it is compiled.
Trait objects are kind of easy to imagine: a heap-allocated dictionary of
methods for that trait. I do wonder how heap allocation is being avoided in
this case.

EDIT: I didn't read closely enough. Only a single type is allowed, so the
traditional existential type construct ("trait objects") are still needed.

~~~
kibwen
There's intentionally no heap allocation or virtual dispatch when using `impl
Trait`; if we were content with that, we wouldn't have bothered implementing
it and just continued on as we were with `Box<Trait>`. :P

------
pjungwir
Oh wow, this sounds great! I've hit both the long signatures when returning
iterators, and also the dereferencing song-and-dance with match, and my Rust
projects have been very limited. So I think these are huge improvements that
will help a lot of other newbies like me. I can't wait to start using 1.26
instead. Thanks Rust team! :-)

------
leshow
I have been so excited for this release! impl Trait is wonderful, thanks
everybody

------
Promarged
Congrats on the release!

Would the book be updated as new features are added to Rust? I see some useful
things being incorporated slowly into the language...

~~~
steveklabnik
Yes and no. Think of it like release trains; the second edition has left the
station, and so isn't being updated directly. It's actually pinned to 1.21; it
left the station a while back.

Work on the "2018 edition", which is the next version after "second edition",
is just starting. It will be getting updates as new stuff lands, though there
may be a bit of lag. In general, docs are going to be a bit weird up to the
Rust 2018 release; it's all coming together, but slower at first, faster at
the end.

(This means that, as of right this moment, there aren't great docs for impl
Trait. I'm working on them right now.)

------
shmerl
Congrats on impl Trait release!

By the way, how is the progress of supporting XDG base directory spec for
rustc and cargo?

~~~
steveklabnik
Moving forward still. It’s non-trivial.

------
jeffdavis
Why is a filtered iterator a different type than an unfiltered iterator?

~~~
GolDDranks
This is hard to answer as a one-liner; do you know about monomorphic vs.
polymorphic code and static/dynamic dispatching? Rust is, by default
statically dispatched, so because the two kinds of iterators do different
things, they have to be of different types.

~~~
jeffdavis
Ah, that makes sense, thank you.

One iterator simply returns the value and increments, and the other needs to
apply the filter first and potentially advance several times.

------
nikolay
I really wonder why is Golang so popular today when Rust is just killing it?

~~~
jkarneges
Aside from the head start, I believe Go legitimately hits a sweet spot for
developers wanting a language that's relatively easy to use yet also fast and
fully compiled.

Rust on the other hand is targeted more towards developers that want C-like
low-level control along with safety against shooting themselves in the foot.

The former audience is probably larger than the latter. But popularity isn't
everything (JavaScript wins that contest ;)). The important thing is Rust is
doing an amazing job in an area that hasn't seen much love.

~~~
orthecreedence
> C-like low-level control along with safety against shooting themselves in
> the foot

Yep, checking in. I want to write libraries that work on Windows, Linux, OSx,
iOS, and Android that expose a C api but without having to write any C.

I _know_ a bit of C, but not enough to feel like I can effectively use it to
build the things I can build with Rust.

~~~
jkarneges
> I know a bit of C, but not enough to feel like I can effectively use it

I love what the Foreward [1] in the Rust Book has to say about this:

"Traditionally, this realm of programming is seen as arcane, accessible only
to a select few who have devoted the necessary years learning to avoid its
infamous pitfalls. And even those who practice it do so with caution, lest
their code be open to exploits, crashes, or corruption.

Rust breaks down these barriers by eliminating the old pitfalls and providing
a friendly, polished set of tools to help you along the way."

[1] [https://doc.rust-lang.org/book/second-
edition/foreword.html](https://doc.rust-lang.org/book/second-
edition/foreword.html)

------
freeopinion
Yeah, but can it run Rocket? :-)

~~~
steveklabnik
Not yet; working on it!
[https://github.com/SergioBenitez/Rocket/issues/19](https://github.com/SergioBenitez/Rocket/issues/19)
is getting shorter and shorter!

~~~
stmw
Definitely excited by all the progress on the "run Rocket" front!

