From 83bb430663b35989cfc968550196c64a7b173cf4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 13 Oct 2018 19:07:17 +0300 Subject: [PATCH 1/3] Revert "rustc_resolve: move extern_prelude from Resolver to Session." This reverts commit e90985acdec9928da9f6d157cfeb64f0ee98bffe. --- src/librustc/session/mod.rs | 18 ------------------ src/librustc_resolve/error_reporting.rs | 2 +- src/librustc_resolve/lib.rs | 20 +++++++++++++++++--- src/librustc_resolve/macros.rs | 2 +- src/librustc_resolve/resolve_imports.rs | 6 +++--- 5 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 10a506da4eab4..8e06191f3dd7f 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, - - /// 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, } pub struct PerfStats { @@ -1149,18 +1144,6 @@ pub fn build_session_( CguReuseTracker::new_disabled() }; - - let mut extern_prelude: FxHashSet = - 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, @@ -1236,7 +1219,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_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index b9194fdfc15d7..74d1ae96e794f 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 = self.resolver.session.extern_prelude + let external_crate_names: BTreeSet = 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 a93cc7ad7518a..1ad41fa058244 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>, + extern_prelude: FxHashSet, /// n.b. This is used only for better diagnostics, not name resolution itself. has_self: FxHashSet, @@ -1676,6 +1677,17 @@ 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 = + session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect(); + + // HACK(eddyb) this ignore the `no_{core,std}` attributes. + // FIXME(eddyb) warn (elsewhere) 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 mut invocations = FxHashMap(); invocations.insert(Mark::root(), arenas.alloc_invocation_data(InvocationData::root(graph_root))); @@ -1694,6 +1706,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // AST. graph_root, prelude: None, + extern_prelude, has_self: FxHashSet(), field_names: FxHashMap(), @@ -1966,7 +1979,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 +4031,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 +4477,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 c31b558dedea0..6c57e6c88abeb 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 6e9877b1ab66d..48f312ce9f27d 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 })) From 522948827b8e691f8f1efce2a87ab813045af60b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 13 Oct 2018 21:21:08 +0300 Subject: [PATCH 2/3] Copy extern prelude from resolver to global context --- src/librustc/ty/context.rs | 3 ++- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/mod.rs | 3 ++- src/librustc_driver/driver.rs | 1 + src/librustc_resolve/lib.rs | 2 +- src/librustc_typeck/check_unused.rs | 2 +- src/librustdoc/core.rs | 1 + 7 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index ab1df2d4c3bb9..5e15ca16b97cd 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -936,8 +936,8 @@ pub struct GlobalCtxt<'tcx> { freevars: FxHashMap>>, maybe_unused_trait_imports: FxHashSet, - maybe_unused_extern_crates: Vec<(DefId, Span)>, + pub extern_prelude: FxHashSet, // Internal cache for metadata decoding. No need to track deps on this. pub rcache: Lock>>, @@ -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 ab0813240364c..ca4cafd0a7391 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 2e8734a6aa8eb..ee6d2dfb065f0 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; @@ -140,6 +140,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, } #[derive(Clone, Copy, PartialEq, Eq, Debug)] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 7fb66ea97f26b..3b0acfd6f8c12 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/lib.rs b/src/librustc_resolve/lib.rs index 1ad41fa058244..8cf3c0f8843a8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1360,7 +1360,7 @@ pub struct Resolver<'a, 'b: 'a> { graph_root: Module<'a>, prelude: Option>, - extern_prelude: FxHashSet, + pub extern_prelude: FxHashSet, /// n.b. This is used only for better diagnostics, not name resolution itself. has_self: FxHashSet, diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index 62ffffab07661..f9aa0397257b8 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 b85604d860be4..4a698e499a7fb 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()), From 894a8d574d0851edf70eba1404a97df535d31e29 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 13 Oct 2018 21:24:50 +0300 Subject: [PATCH 3/3] resolve: Scale back hard-coded extern prelude additions --- src/librustc_resolve/lib.rs | 16 +++++++++------- src/test/ui/rust-2018/issue-54006.stderr | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8cf3c0f8843a8..86fe584dc3a40 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1680,13 +1680,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let mut extern_prelude: FxHashSet = session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect(); - // HACK(eddyb) this ignore the `no_{core,std}` attributes. - // FIXME(eddyb) warn (elsewhere) 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")); + 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(), diff --git a/src/test/ui/rust-2018/issue-54006.stderr b/src/test/ui/rust-2018/issue-54006.stderr index 37bf19e61f8d8..268a16e5d2a0f 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