diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-11-14 02:17:40 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-11-18 13:57:04 +0300 |
| commit | 0e8a97f8e7cf1da19c708d33f56027e1d9d9f067 (patch) | |
| tree | b3986307262622718fef87c10e4ac7a7dd7b7c97 | |
| parent | 8e88c3470a1513f6ad3dabc82f00076977da91ae (diff) | |
| download | rust-0e8a97f8e7cf1da19c708d33f56027e1d9d9f067.tar.gz rust-0e8a97f8e7cf1da19c708d33f56027e1d9d9f067.zip | |
resolve: Avoid marking `extern crate` items as used in certain cases
| -rw-r--r-- | src/librustc_resolve/lib.rs | 20 | ||||
| -rw-r--r-- | src/librustc_resolve/macros.rs | 2 | ||||
| -rw-r--r-- | src/librustc_resolve/resolve_imports.rs | 5 |
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(); |
