Anonymous
Anonymous

Reputation: 13

Why doesn't `use std::{ self, ... };` compile?

I have no idea why this code can't be compiled with Rust 1.27.0.

This is test.rs as it is on my hard drive:

use std::{
  self,
  io::prelude::*,
  net::{ TcpListener, TcpStream },
};

fn main() {}

Output when trying to compile it with rustc test.rs:

error[E0254]: the name `std` is defined multiple times
 --> test.rs:2:5
  |
2 |     self,
  |     ^^^^ `std` reimported here
  |
  = note: `std` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
  |
2 |     self as other_std,
  |     ^^^^^^^^^^^^^^^^^

warning: unused imports: `TcpListener`, `TcpStream`, `io::prelude::*`, `self`
 --> test.rs:2:5
  |
2 |     self,
  |     ^^^^
3 |     io::prelude::*,
  |     ^^^^^^^^^^^^^^
4 |     net::{TcpListener, TcpStream},
  |           ^^^^^^^^^^^  ^^^^^^^^^
  |
  = note: #[warn(unused_imports)] on by default

Upvotes: 1

Views: 284

Answers (1)

Lukas Kalbertodt
Lukas Kalbertodt

Reputation: 88626

This works fine in Rust 2018. You probably just want to update by adding edition = "2018" to your Cargo.toml or --edition=2018 to your rustc invocation. Below is the answer for why this doesn't work in Rust 2015.


From the std::prelude documentation:

On a technical level, Rust inserts

extern crate std;

into the crate root of every crate, and

use std::prelude::v1::*;

into every module.

You can also see that in action when looking at your code after macro expansion (e.g. via cargo-expand). For your code this results in:

#![feature(prelude_import)]
#![no_std]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
// No external crates imports or anything else.

use std::{
    self,
    net::{TcpListener, TcpStream},
};

fn main() {
    // Empty.
}

As you can see, std is already in scope due to the extern crate std; statement. Thus, importing it another time results in this error.

Upvotes: 5

Related Questions