about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-11-14 02:17:40 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-11-18 13:57:04 +0300
commit0e8a97f8e7cf1da19c708d33f56027e1d9d9f067 (patch)
treeb3986307262622718fef87c10e4ac7a7dd7b7c97
parent8e88c3470a1513f6ad3dabc82f00076977da91ae (diff)
downloadrust-0e8a97f8e7cf1da19c708d33f56027e1d9d9f067.tar.gz
rust-0e8a97f8e7cf1da19c708d33f56027e1d9d9f067.zip
resolve: Avoid marking `extern crate` items as used in certain cases
-rw-r--r--src/librustc_resolve/lib.rs20
-rw-r--r--src/librustc_resolve/macros.rs2
-rw-r--r--src/librustc_resolve/resolve_imports.rs5
3 files changed, 20 insertions, 7 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 47ae47a0d73..24a89f7cd54 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1970,14 +1970,26 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         self.arenas.alloc_module(module)
     }
 
-    fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>) {
-        match binding.kind {
+    fn record_use(&mut self, ident: Ident, ns: Namespace,
+                  used_binding: &'a NameBinding<'a>, is_lexical_scope: bool) {
+        match used_binding.kind {
             NameBindingKind::Import { directive, binding, ref used } if !used.get() => {
+                // Avoid marking `extern crate` items that refer to a name from extern prelude,
+                // but not introduce it, as used if they are accessed from lexical scope.
+                if is_lexical_scope {
+                    if let Some(entry) = self.extern_prelude.get(&ident.modern()) {
+                        if let Some(crate_item) = entry.extern_crate_item {
+                            if ptr::eq(used_binding, crate_item) && !entry.introduced_by_item {
+                                return;
+                            }
+                        }
+                    }
+                }
                 used.set(true);
                 directive.used.set(true);
                 self.used_imports.insert((directive.id, ns));
                 self.add_to_glob_map(directive.id, ident);
-                self.record_use(ident, ns, binding);
+                self.record_use(ident, ns, binding, false);
             }
             NameBindingKind::Ambiguity { kind, b1, b2 } => {
                 self.ambiguity_errors.push(AmbiguityError {
@@ -2965,7 +2977,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                             Def::Const(..) if is_syntactic_ambiguity => {
                                 // Disambiguate in favor of a unit struct/variant
                                 // or constant pattern.
-                                self.record_use(ident, ValueNS, binding.unwrap());
+                                self.record_use(ident, ValueNS, binding.unwrap(), false);
                                 Some(PathResolution::new(def))
                             }
                             Def::StructCtor(..) | Def::VariantCtor(..) |
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 814c27bffcd..14e54631f24 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -996,7 +996,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                                                             &parent_scope, true, true, ident.span) {
                 Ok(binding) => {
                     let initial_def = initial_binding.map(|initial_binding| {
-                        self.record_use(ident, MacroNS, initial_binding);
+                        self.record_use(ident, MacroNS, initial_binding, false);
                         initial_binding.def_ignoring_ambiguity()
                     });
                     let def = binding.def_ignoring_ambiguity();
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 68657fedb42..4637e73ee0f 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -234,7 +234,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
                 if self.last_import_segment && check_usable(self, binding).is_err() {
                     Err(DeterminacyExt::Determined)
                 } else {
-                    self.record_use(ident, ns, binding);
+                    self.record_use(ident, ns, binding, restricted_shadowing);
 
                     if let Some(shadowed_glob) = resolution.shadowed_glob {
                         // Forbid expanded shadowing to avoid time travel.
@@ -924,7 +924,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
                     // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
                     let initial_def = result[ns].get().map(|initial_binding| {
                         all_ns_err = false;
-                        this.record_use(ident, MacroNS, initial_binding);
+                        this.record_use(ident, ns, initial_binding,
+                                        directive.module_path.is_empty());
                         initial_binding.def_ignoring_ambiguity()
                     });
                     let def = binding.def_ignoring_ambiguity();