]> git.lizzy.rs Git - rust.git/commitdiff
resolve: Avoid marking `extern crate` items as used in certain cases
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Tue, 13 Nov 2018 23:17:40 +0000 (02:17 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sun, 18 Nov 2018 10:57:04 +0000 (13:57 +0300)
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs

index 47ae47a0d73a00982d05030fe10a0c4b9b66614c..24a89f7cd549c400f6c79ebc268a1746296dbd78 100644 (file)
@@ -1970,14 +1970,26 @@ fn new_module(
         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 @@ fn resolve_pattern(&mut self,
                             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(..) |
index 814c27bffcd1d655b3968c8db6eb2e10070e9ad2..14e54631f2409634647f093a3fe5d615a3f74831 100644 (file)
@@ -996,7 +996,7 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
                                                             &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();
index 68657fedb42a81a709d234895c9c275121899293..4637e73ee0fbb6e699055e253e15d5fb9717e81e 100644 (file)
@@ -234,7 +234,7 @@ fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
                 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 @@ fn finalize_import(
                     // 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();