Announcing Rust 2018 Preview 2!

Today marks another milestone toward Rust 2018: we’re announcing the 2018 Edition Preview 2 . Like the last preview, this is an alpha-quality preview of Rust 2018 intended for testing and feedback. It is only available on the nightly release channel. Compared to Preview 1, we’ve made a number of changes:

  • The cargo fix command, used during migration, is now a built-in part of Cargo, which further streamlines the migration process.

  • Extensive work has gone in to fix and polish the lints that help you migrate. At this point we expect a smooth experience for the majority of crates. If you have any problems during migration, please file an issue.

  • The module system changes have been broken into several smaller features with independent tracking issues for feedback and discussion:

    • Changes to the way that paths in use statements work (tracked here). There are two variants of the design we’re collecting feedback on, see the Edition Guide for detail; we’re especially seeking feedback on the #![feature(uniform_paths)] variant, new in Preview 2.
    • No longer requiring for parent modules (tracked here).
    • No longer requiring extern crate for including dependencies (tracked here).
    • Supporting crate as a visibility modifier (tracked here. Given feedback so far, this feature is unlikely to be stabilized for Rust 2018.
  • NLL has been enabled by default, in migration mode:

    • If your code is accepted by NLL, then we accept it.
    • If your code is rejected by both NLL and the old borrow checker, then we reject it.
    • If your code is rejected by NLL but accepted by the old borrow checker, then we emit the new NLL errors as warnings.
    • Please report warnings you encounter that you think are wrong!
  • In-band lifetimes have been split up

    • Complete elision in headers (impl Debug for &MyType) still in, tracked here.
    • Anything beyond that has been removed from the 2018 edition feature gate, due to mixed feedback (tracked here)
  • Both rustfmt and the RLS have reached 1.0 “release candidate” status. Look for more information about that soon.

What this milestone means

We have now entered the final release cycle before Rust 2018 goes into beta. By the end of this release cycle (September 13th), we need to have reached final stabilization decisions for the remaining features. The last major feature that is still not fully nailed down is the module system changes, particularly the precise approach to paths .

At the end of this cycle we will produce Rust 1.30 Beta, which will have all the Rust 2018 features stabilized, including the feature gate for the 2018 Edition itself . At that point we will make a high profile announcement and look for feedback on the quality of the overall product (but not on which features to ship). We will continue this beta into 1.31, giving us three months of final testing, feedback, and polish before releasing Rust 2018 to the world on December 6th.


I wanted to give a special thanks to @petrochenkov, @eddyb, @josh, @centril, @Mark_Simulacrum, @alexcrichton, @killercup, @steveklabnik, the NLL working group, and the Dev Tools team, all of whom did a ton of work going into this preview. (I’m sure I’m missing someone on this list, so please feel free to give additional shoutouts! <3)


I also want to give my thanks to @aturon who has been instrumental in getting this preview shipped. :heart:


Note for everyone testing out uniform_paths: a fix for suboptimal/wrong diagnostics is up:

I really liked the new module system, and I think it would be a shame if it were changed.

When I see a use statement I really like that I instantly know what it refers to. The proposal also eliminates ::this::pattern which confused me when I started. I think the mental model is simpler and would allow me to write better code.

I worry that the uniform proposal will be attractive because it feels more similar to the current system.

1 Like

The link to “The cargo fix command” seems to be broken, my best guess is that it should point to:


Update: next nightly should now includes these Rust 2018 changes:

As a (very) new Rustacean, it's awesome to see the speed at which the Rust community moves forward, while also still keeping backward compatibility in mind.

I had one question about this quote:

Both rustfmt and the RLS have reached 1.0 “release candidate” status. Look for more information about that soon.

I'm eagerly awaiting the "more information" part, but until then, I wonder what "1.0" means for these tools, specifically for RLS.

As a developer, I enjoy learning new programming languages (and especially the standard library) by exploring. Building small utilities in my editor, creating a variable of one type, and allowing code completion to guide me towards the capabilities of each type and how they function.

In Rust, this hasn't been such a great experience so far, unfortunately.

Specifically, RLS (and Racer) hasn't been able to complete quite some code that I've been playing with. Maybe it's just my set up, but from what I've read, I'm not the only one experiencing this, and this is because the compiler - for now - can't give RLS (all) the information it needs, having it fall back to the less accurate Racer, resulting in no code completion to show up at all, or a "goto" action going to a similarly named, but differently namespaced type.

Specifically, here are two GH issues I replied to:

The biggest problem with this is that it interrupts the workflow. When no auto-completion shows up, you start to wonder "did I do something wrong? Or is this an RLS issue? Should I report it, or is this known because of the lack of compiler support?" The next step then is to go open the (awesome!) Rust docs to find more information about that type and the methods it supports.

So my question/remark would be: if my findings are accurate, and RLS isn't that reliable yet, what's the main reason to already move it to 1.0, instead of letting it bake a bit more until its reliability is high enough?


If the lack of auto-completion the RLS is giving is causing you problems, you could also try out IntelliJ Rust, which has it's own, separate, Rust compiler/inference engine written in Kotlin. It will still have deficiencies, but for your use case it might work better. I've personally found it to be quite good and saved me huge amounts of time learning new Rust libraries.

Thank you @johnthagen for the tip. I greatly appreciate the help. I am aware of the Jetbrains IDEs, but I’m not a fan of their visual clutter. I prefer vscode or sublime text (and accept the shortcomings that come with that).

My post wasn’t really a “help me find a solution” post, as I’m aware this is not the post (or the forum) to do so, but I wanted to give a quick insight into how a starting Rustacean is struggling with the current status of RLS, in case that helps in any way working towards a 1.0 release.


The 2018 preview right now has relaxed the rule that we cannot call Box<dyn FnOnce>. However a CUP (Compiler UnexpectedUnconscious Panic, a much more serious problem than ICEs) was caused by this relax. The minimum reproducable is suprisingly simple, suggest that the shipping of this relax was not even tested with simplest use case.


fn foo(f: Box<dyn FnOnce()>) {
fn main() {}

(Rejected in 2015, CUP in 2018)

Tenichally speaking, the relax of the rule has nothing to do with the CUP. What it actually does is just triggering a bug that, when the MIR verifier have an inconsistent view of the program with the compiled code, it will not be able to handle some generated MIR, and crashes. In such a case, normally the compiler main thread shall catch the crash and report an error, but it didn’t because the crashed thread is in a “poisoned” state and so the main thread have no choice but panic.

EDIT I have created a post in rust users forum, talking about my observations on this bug. I appreciate any help for me to understand the code.

A pull request is now created.

1 Like

Uh, what? This is not a real distinction that I'm aware of. The majority of ICEs are caused by panics.


The keyword here is "unexpected", means the compiler have no idea about what the real problem is.

Other ICEs, on the other hand, usually will give you something that "Type mismatch when expected to match" or "Bad MIR" etc.

You’re reading too much into the message the compiler’s panic hook printed. All ICEs are caused by the compiler encountering some state it doesn’t understand.


To the end user, they are the same: you will see some messages that you are not suppose to understand;

But to the developers of the compiler, they are different. Normal ICEs like this one, will let you understand that the problem is in a struct called

OutputTypeParameterMismatch(Binder(<[closure@src/ 13:24] as std::ops::FnMut<(<Id<()> as Lt<'_>>::T,)>>), Binder(<[closure@src/ 13:24] as std::ops::FnMut<((),)>>), Sorts(ExpectedFound { expected: (), found: <Id<()> as Lt<'_>>::T }))` selecting `Binder(<[closure@src/ 13:24] as std::ops::FnMut<((),)>>)

and makes the diagnostic and fix much easier. The compiler developers can easily spot out: the compiler was consider () is matching <() as Lt<'_>>::T, but later it didn’t match them. This is inconsistent and so you can dig deeper into it and fix it.

But CUPs on the other hand, if gives you anything ever, it is something that is irrelevant to the program being compiling. This is harder to trace and debug.

The compiler output for the “normal ICE” you linked literally contains the phrase “compiler unexpectedly panicked”.


Yes… But I feel like I need to distinguish them anyways. Maybe “Compiler Unconscious Panic” would be a better term? Difference: normal panic is that you get killed but you can shout the name of the murderer, CUP is on the other hand the case when you get killed asleep…

EDIT OK, my investigate on this shows that “CUP” is a rare unfortunate situation simply because some code should be put in a scope to access the source code position but it was not. So after this has been fixed, there should be no more "CUP"s any more.

I had a bit of an issue with the documentation in the Edition Guide regarding path clarity.

The documentation gave me the impression that extern crate removal had already landed on nightly but the functionality isn’t there yet. It would be helpful if the status of the independent tracking issues could be integrated into the edition guide in some way. That way it would be easier to distinguish “not yet available” from an actual bug.

extern crate is no longer needed, as long as you opt-in to the 2018 edition. Make sure you're using the nightly compiler and that you've enabled the 2018 edition.

Add this to your Cargo.toml:

cargo-features = ["edition"]

edition = '2018'

That cargo-features line should go at the very top; and edition goes into the [package] section.


I added #![feature(rust_2018_preview, uniform_paths)] to my sources and executed cargo fix --allow-dirty --edition. That changed crate-internal use to the new use crate:: but kept all extern crate lines. I thought this was already the opt-in.

And the issue indicates (“disposition-merge”?) that its not yet included in Rust 2018 nightly… unless I miss(understand) something, which is entirely possible.