diff options
| author | bors <bors@rust-lang.org> | 2016-09-06 01:44:13 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-09-06 01:44:13 -0700 |
| commit | 5114f8a29ba29c7a168b46ede82fb62d67a2d619 (patch) | |
| tree | 2cf55f7fc2bf91a05c0d732bb737a24f2631d864 | |
| parent | 1d04201565790e17890f300c2bedeab6b895c313 (diff) | |
| parent | ff3a6449512e9e6fd1ea455c64cd02a7fa4cc7e2 (diff) | |
| download | rust-5114f8a29ba29c7a168b46ede82fb62d67a2d619.tar.gz rust-5114f8a29ba29c7a168b46ede82fb62d67a2d619.zip | |
Auto merge of #36276 - jseyfried:fix_unused, r=nrc
resolve: Fix unused import false positive with `item_like_imports` Fixes #36249. r? @nrc
| -rw-r--r-- | src/librustc_resolve/lib.rs | 46 | ||||
| -rw-r--r-- | src/librustc_resolve/resolve_imports.rs | 1 | ||||
| -rw-r--r-- | src/test/compile-fail/imports/unused.rs | 38 |
3 files changed, 63 insertions, 22 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0420fa80268..c5b505fba38 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -871,6 +871,7 @@ enum NameBindingKind<'a> { Import { binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>, + used: Cell<bool>, }, Ambiguity { b1: &'a NameBinding<'a>, @@ -878,9 +879,15 @@ enum NameBindingKind<'a> { } } -#[derive(Clone, Debug)] struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>); +struct AmbiguityError<'a> { + span: Span, + name: Name, + b1: &'a NameBinding<'a>, + b2: &'a NameBinding<'a>, +} + impl<'a> NameBinding<'a> { fn module(&self) -> Result<Module<'a>, bool /* true if an error has already been reported */> { match self.kind { @@ -938,14 +945,6 @@ impl<'a> NameBinding<'a> { _ => true, } } - - fn ambiguity(&self) -> Option<(&'a NameBinding<'a>, &'a NameBinding<'a>)> { - match self.kind { - NameBindingKind::Ambiguity { b1, b2 } => Some((b1, b2)), - NameBindingKind::Import { binding, .. } => binding.ambiguity(), - _ => None, - } - } } /// Interns the names of the primitive types. @@ -1064,7 +1063,7 @@ pub struct Resolver<'a> { pub maybe_unused_trait_imports: NodeSet, privacy_errors: Vec<PrivacyError<'a>>, - ambiguity_errors: Vec<(Span, Name, &'a NameBinding<'a>)>, + ambiguity_errors: Vec<AmbiguityError<'a>>, arenas: &'a ResolverArenas<'a>, dummy_binding: &'a NameBinding<'a>, @@ -1276,17 +1275,21 @@ impl<'a> Resolver<'a> { self.used_crates.insert(krate); } - if let NameBindingKind::Import { directive, .. } = binding.kind { - self.used_imports.insert((directive.id, ns)); - self.add_to_glob_map(directive.id, name); - } - - if binding.ambiguity().is_some() { - self.ambiguity_errors.push((span, name, binding)); - return true; + match binding.kind { + NameBindingKind::Import { directive, binding, ref used } if !used.get() => { + used.set(true); + self.used_imports.insert((directive.id, ns)); + self.add_to_glob_map(directive.id, name); + self.record_use(name, ns, binding, span) + } + NameBindingKind::Import { .. } => false, + NameBindingKind::Ambiguity { b1, b2 } => { + let ambiguity_error = AmbiguityError { span: span, name: name, b1: b1, b2: b2 }; + self.ambiguity_errors.push(ambiguity_error); + true + } + _ => false } - - false } fn add_to_glob_map(&mut self, id: NodeId, name: Name) { @@ -3306,9 +3309,8 @@ impl<'a> Resolver<'a> { fn report_errors(&self) { let mut reported_spans = FnvHashSet(); - for &(span, name, binding) in &self.ambiguity_errors { + for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors { if !reported_spans.insert(span) { continue } - let (b1, b2) = binding.ambiguity().unwrap(); let msg1 = format!("`{}` could resolve to the name imported here", name); let msg2 = format!("`{}` could also resolve to the name imported here", name); self.session.struct_span_err(span, &format!("`{}` is ambiguous", name)) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 875d6745f6b..85c03683c8d 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -308,6 +308,7 @@ impl<'a> Resolver<'a> { kind: NameBindingKind::Import { binding: binding, directive: directive, + used: Cell::new(false), }, span: directive.span, vis: vis, diff --git a/src/test/compile-fail/imports/unused.rs b/src/test/compile-fail/imports/unused.rs new file mode 100644 index 00000000000..4ec9987df42 --- /dev/null +++ b/src/test/compile-fail/imports/unused.rs @@ -0,0 +1,38 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(pub_restricted, item_like_imports)] +#![deny(unused)] + +mod foo { + fn f() {} + + mod m1 { + pub(super) use super::f; //~ ERROR unused + } + + mod m2 { + #[allow(unused)] + use super::m1::*; // (despite this glob import) + } + + mod m3 { + pub(super) use super::f; // Check that this is counted as used (c.f. #36249). + } + + pub mod m4 { + use super::m3::*; + pub fn g() { f(); } + } +} + +fn main() { + foo::m4::g(); +} |
