diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index b6e03b66510e5..ee98cc6cf927e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -865,7 +865,7 @@ where krate = time(sess, "crate injection", || { let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| &**s); - syntax::std_inject::maybe_inject_crates_ref(krate, alt_std_name) + syntax::std_inject::maybe_inject_crates_ref(krate, alt_std_name, sess.edition()) }); let mut addl_plugins = Some(addl_plugins); diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 68121d42b69c6..626a610017d42 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -11,6 +11,8 @@ use ast; use attr; use std::cell::Cell; +use std::iter; +use edition::Edition; use ext::hygiene::{Mark, SyntaxContext}; use symbol::{Symbol, keywords}; use syntax_pos::{DUMMY_SP, Span}; @@ -43,7 +45,13 @@ thread_local! { static INJECTED_CRATE_NAME: Cell> = Cell::new(None); } -pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str>) -> ast::Crate { +pub fn maybe_inject_crates_ref( + mut krate: ast::Crate, + alt_std_name: Option<&str>, + edition: Edition, +) -> ast::Crate { + let rust_2018 = edition >= Edition::Edition2018; + // the first name in this list is the crate name of the crate with the prelude let names: &[&str] = if attr::contains_name(&krate.attrs, "no_core") { return krate; @@ -58,14 +66,27 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str> }; // .rev() to preserve ordering above in combination with insert(0, ...) - for name in names.iter().rev() { + let alt_std_name = alt_std_name.map(Symbol::intern); + for orig_name in names.iter().rev() { + let orig_name = Symbol::intern(orig_name); + let mut rename = orig_name; + // HACK(eddyb) gensym the injected crates on the Rust 2018 edition, + // so they don't accidentally interfere with the new import paths. + if rust_2018 { + rename = orig_name.gensymed(); + } + let orig_name = if rename != orig_name { + Some(orig_name) + } else { + None + }; krate.module.items.insert(0, P(ast::Item { attrs: vec![attr::mk_attr_outer(DUMMY_SP, attr::mk_attr_id(), attr::mk_word_item(ast::Ident::from_str("macro_use")))], vis: dummy_spanned(ast::VisibilityKind::Inherited), - node: ast::ItemKind::ExternCrate(alt_std_name.map(Symbol::intern)), - ident: ast::Ident::from_str(name), + node: ast::ItemKind::ExternCrate(alt_std_name.or(orig_name)), + ident: ast::Ident::with_empty_ctxt(rename), id: ast::DUMMY_NODE_ID, span: DUMMY_SP, tokens: None, @@ -91,9 +112,11 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str> vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited), node: ast::ItemKind::Use(P(ast::UseTree { prefix: ast::Path { - segments: [name, "prelude", "v1"].into_iter().map(|name| { - ast::PathSegment::from_ident(ast::Ident::from_str(name)) - }).collect(), + segments: iter::once(keywords::CrateRoot.ident()) + .chain( + [name, "prelude", "v1"].iter().cloned() + .map(ast::Ident::from_str) + ).map(ast::PathSegment::from_ident).collect(), span, }, kind: ast::UseTreeKind::Glob, diff --git a/src/test/pretty/cast-lt.pp b/src/test/pretty/cast-lt.pp index f1b4b4f5a0c8a..b8d920754ad79 100644 --- a/src/test/pretty/cast-lt.pp +++ b/src/test/pretty/cast-lt.pp @@ -1,7 +1,7 @@ #![feature(prelude_import)] #![no_std] #[prelude_import] -use std::prelude::v1::*; +use ::std::prelude::v1::*; #[macro_use] extern crate std; // Copyright 2017 The Rust Project Developers. See the COPYRIGHT diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index a4380d9212fdf..5f42b86c82a81 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -1,5 +1,5 @@ #[prelude_import] -use std::prelude::v1::*; +use ::std::prelude::v1::*; #[macro_use] extern crate std; // Copyright 2014 The Rust Project Developers. See the COPYRIGHT