26

I would like to know, why sometimes we need to use extern crate over use? I'm using the crate wee_alloc and to import its modules I have to use extern crate:

extern crate wee_alloc;

// Use `wee_alloc` as the global allocator.
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

But with web_sys I can just use use.

4
  • 1
    You don't need the extern crate - only if you are using edition 2015.
    – Peter Hall
    Commented Oct 31, 2020 at 16:11
  • I'm using the latest version of rust and I see no wee_alloc external crate error when using use instead of extern crate. Commented Oct 31, 2020 at 16:16
  • Can you provide the entire error message? Commented Oct 31, 2020 at 16:26
  • In 2021 there is no need to use it. Commented May 2, 2021 at 20:01

1 Answer 1

47

tldr: You do not need to write extern crate anymore for external dependencies in Rust 2018. The code you provided without extern crate works just fine with edition = "2018" set in your Cargo.toml

No more extern crate

You no longer need to write extern crate to import a crate into your project. Before:

// Rust 2015

extern crate futures;

mod foo {
    use futures::Future;
}

After:

// Rust 2018

mod foo {
    use futures::Future;
}

Macros

One other use for extern crate was to import macros; that's no longer needed. In Rust 2015, you would have written:

// Rust 2015

#[macro_use]
extern crate log;

fn main() {
    error!("oops");
}

Now, you write:

// Rust 2018

use log::error;

fn main() {
    error!("oops");
}

Renaming crates

If you've been using as to rename your crate like this:

extern crate futures as fut;

Then in Rust 2018, you simply do this:

use futures as fut;

use fut::Future;

Sysroot Crates

There's one exception to this rule, and that's the "sysroot" crates. These are the crates distributed with Rust itself. For now, you still need to use extern crate for these crates:

  • proc_macro
  • core
  • std

However, extern crate std and extern crate core are already implicit, so it is very rare that you will need to declare them manually.

Finally, on nightly, you'll need it for crates like:

  • alloc
  • test

Those are the only exceptions to the rule. Therefore, the code you provided without extern crate works just fine in Rust 2018:

#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

Setting your Rust Edition

Just because you have the latest Rust version installed does not mean that you are compiling with the latest edition. To tell Cargo to use a specific edition, set the edition key/value pair. For example:

[package]
name = "foo"
edition = "2018"

If there's no edition key, Cargo will default to Rust 2015. But in this case, we've chosen 2018, and so our code is compiling with Rust 2018! Thanks to @KevinReid for pointing this out

This answer was derived from The Rust Edition Guide

5
  • That partially answers my question. I still need to use extern crate wee_alloc, otherwise the error pops up when compiling: no wee_alloc external crate Commented Oct 31, 2020 at 16:20
  • The code at the end of my answer does not work for you? What edition of Rust are you using? Commented Oct 31, 2020 at 16:21
  • 1
    This answer doesn't mention that you need to specify the edition in your Cargo.toml — otherwise it defaults to '2015' for backwards compatibility.
    – Kevin Reid
    Commented Oct 31, 2020 at 16:22
  • 2
    I think the distinction that's missing is that having installed an up-to-date version Rust does not mean that the chosen language edition will be the latest.
    – Kevin Reid
    Commented Oct 31, 2020 at 19:35
  • Not a Rust expert, but I am in a no_std environment and using the alloc crate, which requires extern crate alloc with Rust 2018 edition. Commented Jan 19 at 20:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.