about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-17 01:59:28 +0000
committerbors <bors@rust-lang.org>2018-10-17 01:59:28 +0000
commit37ba1071c626c43a5b85752b4ffcf6a87e2b745e (patch)
treefb99c20ee80261584dc85fb47ac322f6e0fb1076
parent01ca85becd45a4115bd5a1b367a1667c06f0906b (diff)
parent894a8d574d0851edf70eba1404a97df535d31e29 (diff)
downloadrust-37ba1071c626c43a5b85752b4ffcf6a87e2b745e.tar.gz
rust-37ba1071c626c43a5b85752b4ffcf6a87e2b745e.zip
Auto merge of #54671 - petrochenkov:extpre2015, r=nikomatsakis
resolve: Scale back hard-coded extern prelude additions on 2015 edition

https://github.com/rust-lang/rust/pull/54404 stabilized `feature(extern_prelude)` on 2015 edition, including the hard-coded parts not passed with `--extern`.
First of all, I'd want to confirm that this is intended stabilization, rather than a part of the "extended beta" scheme that's going to be reverted before releasing stable.
(EDIT: to clarify - this is a question, I'm \*asking\* for confirmation, rather than give it.)

Second, on 2015 edition extern prelude is not so fundamentally tied to imports and is a mere convenience, so this PR scales them back to the uncontroversial subset.
The "uncontroversial subset" means that if libcore is injected it brings `core` into prelude, if libstd is injected it brings `std` and `core` into prelude.
On 2015 edition this can be implemented through the library prelude (rather than hard-coding in the compiler) right now, I'll do it in a follow-up PR.

UPDATE: The change is done for both 2015 and 2018 editions now as discussed below.

Closes https://github.com/rust-lang/rust/issues/53166
-rw-r--r--src/librustc/session/mod.rs18
-rw-r--r--src/librustc/ty/context.rs3
-rw-r--r--src/librustc/ty/item_path.rs2
-rw-r--r--src/librustc/ty/mod.rs3
-rw-r--r--src/librustc_driver/driver.rs1
-rw-r--r--src/librustc_resolve/error_reporting.rs2
-rw-r--r--src/librustc_resolve/lib.rs22
-rw-r--r--src/librustc_resolve/macros.rs2
-rw-r--r--src/librustc_resolve/resolve_imports.rs6
-rw-r--r--src/librustc_typeck/check_unused.rs2
-rw-r--r--src/librustdoc/core.rs1
-rw-r--r--src/test/ui/rust-2018/issue-54006.stderr2
12 files changed, 33 insertions, 31 deletions
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index e983ddc3108..1ca60d54f7a 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -35,7 +35,6 @@ use syntax::edition::Edition;
 use syntax::feature_gate::{self, AttributeType};
 use syntax::json::JsonEmitter;
 use syntax::source_map;
-use syntax::symbol::Symbol;
 use syntax::parse::{self, ParseSess};
 use syntax_pos::{MultiSpan, Span};
 use util::profiling::SelfProfiler;
@@ -166,10 +165,6 @@ pub struct Session {
 
     /// Cap lint level specified by a driver specifically.
     pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
-
-    /// All the crate names specified with `--extern`, and the builtin ones.
-    /// Starting with the Rust 2018 edition, absolute paths resolve in this set.
-    pub extern_prelude: FxHashSet<Symbol>,
 }
 
 pub struct PerfStats {
@@ -1137,18 +1132,6 @@ pub fn build_session_(
         CguReuseTracker::new_disabled()
     };
 
-
-    let mut extern_prelude: FxHashSet<Symbol> =
-        sopts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();
-
-    // HACK(eddyb) this ignores the `no_{core,std}` attributes.
-    // FIXME(eddyb) warn (somewhere) if core/std is used with `no_{core,std}`.
-    // if !attr::contains_name(&krate.attrs, "no_core") {
-    // if !attr::contains_name(&krate.attrs, "no_std") {
-    extern_prelude.insert(Symbol::intern("core"));
-    extern_prelude.insert(Symbol::intern("std"));
-    extern_prelude.insert(Symbol::intern("meta"));
-
     let sess = Session {
         target: target_cfg,
         host,
@@ -1224,7 +1207,6 @@ pub fn build_session_(
         has_global_allocator: Once::new(),
         has_panic_handler: Once::new(),
         driver_lint_caps: FxHashMap(),
-        extern_prelude,
     };
 
     validate_commandline_args_with_session_available(&sess);
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 6f0f258a217..1bccd05af83 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -936,8 +936,8 @@ pub struct GlobalCtxt<'tcx> {
     freevars: FxHashMap<DefId, Lrc<Vec<hir::Freevar>>>,
 
     maybe_unused_trait_imports: FxHashSet<DefId>,
-
     maybe_unused_extern_crates: Vec<(DefId, Span)>,
+    pub extern_prelude: FxHashSet<ast::Name>,
 
     // Internal cache for metadata decoding. No need to track deps on this.
     pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
@@ -1223,6 +1223,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                     .into_iter()
                     .map(|(id, sp)| (hir.local_def_id(id), sp))
                     .collect(),
+            extern_prelude: resolutions.extern_prelude,
             hir,
             def_path_hash_to_def_id,
             queries: query::Queries::new(
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index c4a25971da3..2e635c6ecde 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -289,7 +289,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 // printing the `CrateRoot` so we don't prepend a `crate::` to paths.
                 let mut is_prelude_crate = false;
                 if let DefPathData::CrateRoot = self.def_key(parent_did).disambiguated_data.data {
-                    if self.sess.extern_prelude.contains(&data.as_interned_str().as_symbol()) {
+                    if self.extern_prelude.contains(&data.as_interned_str().as_symbol()) {
                         is_prelude_crate = true;
                     }
                 }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 4135d499c58..45a70be5842 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -36,7 +36,7 @@ use ty::subst::{Subst, Substs};
 use ty::util::{IntTypeExt, Discr};
 use ty::walk::TypeWalker;
 use util::captures::Captures;
-use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
+use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet};
 use arena::SyncDroplessArena;
 use session::DataTypeKind;
 
@@ -141,6 +141,7 @@ pub struct Resolutions {
     pub maybe_unused_trait_imports: NodeSet,
     pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
     pub export_map: ExportMap,
+    pub extern_prelude: FxHashSet<Name>,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 223df7cbb18..4f48b00c937 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -790,6 +790,7 @@ where
                 trait_map: resolver.trait_map,
                 maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
                 maybe_unused_extern_crates: resolver.maybe_unused_extern_crates,
+                extern_prelude: resolver.extern_prelude,
             },
 
             analysis: ty::CrateAnalysis {
diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs
index b9194fdfc15..74d1ae96e79 100644
--- a/src/librustc_resolve/error_reporting.rs
+++ b/src/librustc_resolve/error_reporting.rs
@@ -136,7 +136,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         // Need to clone else we can't call `resolve_path` without a borrow error. We also store
         // into a `BTreeMap` so we can get consistent ordering (and therefore the same diagnostic)
         // each time.
-        let external_crate_names: BTreeSet<Symbol> = self.resolver.session.extern_prelude
+        let external_crate_names: BTreeSet<Symbol> = self.resolver.extern_prelude
             .clone().drain().collect();
 
         // Insert a new path segment that we can replace.
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index a93cc7ad751..86fe584dc3a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1360,6 +1360,7 @@ pub struct Resolver<'a, 'b: 'a> {
     graph_root: Module<'a>,
 
     prelude: Option<Module<'a>>,
+    pub extern_prelude: FxHashSet<Name>,
 
     /// n.b. This is used only for better diagnostics, not name resolution itself.
     has_self: FxHashSet<DefId>,
@@ -1676,6 +1677,19 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         DefCollector::new(&mut definitions, Mark::root())
             .collect_root(crate_name, session.local_crate_disambiguator());
 
+        let mut extern_prelude: FxHashSet<Name> =
+            session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();
+
+        if !attr::contains_name(&krate.attrs, "no_core") {
+            extern_prelude.insert(Symbol::intern("core"));
+            if !attr::contains_name(&krate.attrs, "no_std") {
+                extern_prelude.insert(Symbol::intern("std"));
+                if session.rust_2018() {
+                    extern_prelude.insert(Symbol::intern("meta"));
+                }
+            }
+        }
+
         let mut invocations = FxHashMap();
         invocations.insert(Mark::root(),
                            arenas.alloc_invocation_data(InvocationData::root(graph_root)));
@@ -1694,6 +1708,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             // AST.
             graph_root,
             prelude: None,
+            extern_prelude,
 
             has_self: FxHashSet(),
             field_names: FxHashMap(),
@@ -1966,7 +1981,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
 
         if !module.no_implicit_prelude {
             // `record_used` means that we don't try to load crates during speculative resolution
-            if record_used && ns == TypeNS && self.session.extern_prelude.contains(&ident.name) {
+            if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) {
                 let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
                 let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
                 self.populate_module_if_necessary(&crate_root);
@@ -4018,7 +4033,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                     } else {
                         // Items from the prelude
                         if !module.no_implicit_prelude {
-                            names.extend(self.session.extern_prelude.iter().cloned());
+                            names.extend(self.extern_prelude.iter().cloned());
                             if let Some(prelude) = self.prelude {
                                 add_module_candidates(prelude, &mut names);
                             }
@@ -4464,7 +4479,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         );
 
         if self.session.rust_2018() {
-            for &name in &self.session.extern_prelude {
+            let extern_prelude_names = self.extern_prelude.clone();
+            for &name in extern_prelude_names.iter() {
                 let ident = Ident::with_empty_ctxt(name);
                 match self.crate_loader.maybe_process_path_extern(name, ident.span) {
                     Some(crate_id) => {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index c31b558dede..6c57e6c88ab 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -692,7 +692,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     }
                 }
                 WhereToResolve::ExternPrelude => {
-                    if use_prelude && self.session.extern_prelude.contains(&ident.name) {
+                    if use_prelude && self.extern_prelude.contains(&ident.name) {
                         let crate_id =
                             self.crate_loader.process_path_extern(ident.name, ident.span);
                         let crate_root =
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 6e9877b1ab6..48f312ce9f2 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -199,7 +199,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
                     if !(
                         ns == TypeNS &&
                         !ident.is_path_segment_keyword() &&
-                        self.session.extern_prelude.contains(&ident.name)
+                        self.extern_prelude.contains(&ident.name)
                     ) {
                         // ... unless the crate name is not in the `extern_prelude`.
                         return binding;
@@ -218,7 +218,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
                 } else if
                     ns == TypeNS &&
                     !ident.is_path_segment_keyword() &&
-                    self.session.extern_prelude.contains(&ident.name)
+                    self.extern_prelude.contains(&ident.name)
                 {
                     let crate_id =
                         self.crate_loader.process_path_extern(ident.name, ident.span);
@@ -736,7 +736,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         let uniform_paths_feature = self.session.features_untracked().uniform_paths;
         for ((span, _, ns), results) in uniform_paths_canaries {
             let name = results.name;
-            let external_crate = if ns == TypeNS && self.session.extern_prelude.contains(&name) {
+            let external_crate = if ns == TypeNS && self.extern_prelude.contains(&name) {
                 let crate_id =
                     self.crate_loader.process_path_extern(name, span);
                 Some(Def::Mod(DefId { krate: crate_id, index: CRATE_DEF_INDEX }))
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index 62ffffab076..f9aa0397257 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -164,7 +164,7 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
         // If the extern crate isn't in the extern prelude,
         // there is no way it can be written as an `use`.
         let orig_name = extern_crate.orig_name.unwrap_or(item.name);
-        if !tcx.sess.extern_prelude.contains(&orig_name) {
+        if !tcx.extern_prelude.contains(&orig_name) {
             continue;
         }
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index b85604d860b..4a698e499a7 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -474,6 +474,7 @@ pub fn run_core(search_paths: SearchPaths,
             trait_map: resolver.trait_map.clone(),
             maybe_unused_trait_imports: resolver.maybe_unused_trait_imports.clone(),
             maybe_unused_extern_crates: resolver.maybe_unused_extern_crates.clone(),
+            extern_prelude: resolver.extern_prelude.clone(),
         };
         let analysis = ty::CrateAnalysis {
             access_levels: Lrc::new(AccessLevels::default()),
diff --git a/src/test/ui/rust-2018/issue-54006.stderr b/src/test/ui/rust-2018/issue-54006.stderr
index 37bf19e61f8..268a16e5d2a 100644
--- a/src/test/ui/rust-2018/issue-54006.stderr
+++ b/src/test/ui/rust-2018/issue-54006.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `alloc`
   --> $DIR/issue-54006.rs:16:5
    |
 LL | use alloc::vec;
-   |     ^^^^^ Did you mean `std::alloc`?
+   |     ^^^^^ Did you mean `core::alloc`?
 
 error: cannot determine resolution for the macro `vec`
   --> $DIR/issue-54006.rs:20:18