From 32674b3f1ae0408ca7cb0369eca2efd2f893e908 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 5 Sep 2016 04:55:12 +0000 Subject: [PATCH 1/4] Avoid false positive unused import warnings. --- src/librustc_resolve/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0420fa8026884..cefa37c9fc3b8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1276,16 +1276,17 @@ 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; } + if let NameBindingKind::Import { directive, binding } = binding.kind { + self.used_imports.insert((directive.id, ns)); + self.add_to_glob_map(directive.id, name); + self.record_use(name, ns, binding, span); + } + false } From 07f8cb28dc713b8754ed8b51fd9eb07a2f6325ba Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 5 Sep 2016 05:10:50 +0000 Subject: [PATCH 2/4] Add regression test. --- src/test/compile-fail/imports/unused.rs | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/test/compile-fail/imports/unused.rs diff --git a/src/test/compile-fail/imports/unused.rs b/src/test/compile-fail/imports/unused.rs new file mode 100644 index 0000000000000..4ec9987df4208 --- /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 or the MIT license +// , 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(); +} From 888a968139986847623bc40b5a7dc308cf44f988 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 5 Sep 2016 05:27:58 +0000 Subject: [PATCH 3/4] Add field `used: Cell` to variant `NameBindingKind::Import`. --- src/librustc_resolve/lib.rs | 38 +++++++++++-------------- src/librustc_resolve/resolve_imports.rs | 1 + 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index cefa37c9fc3b8..f3044e1847d1b 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, }, Ambiguity { b1: &'a NameBinding<'a>, @@ -938,14 +939,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 +1057,7 @@ pub struct Resolver<'a> { pub maybe_unused_trait_imports: NodeSet, privacy_errors: Vec>, - ambiguity_errors: Vec<(Span, Name, &'a NameBinding<'a>)>, + ambiguity_errors: Vec<(Span, Name, &'a NameBinding<'a>, &'a NameBinding<'a>)>, arenas: &'a ResolverArenas<'a>, dummy_binding: &'a NameBinding<'a>, @@ -1276,18 +1269,20 @@ impl<'a> Resolver<'a> { self.used_crates.insert(krate); } - if binding.ambiguity().is_some() { - self.ambiguity_errors.push((span, name, binding)); - return true; - } - - if let NameBindingKind::Import { directive, binding } = binding.kind { - self.used_imports.insert((directive.id, ns)); - self.add_to_glob_map(directive.id, name); - self.record_use(name, ns, binding, span); + 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 } => { + self.ambiguity_errors.push((span, name, b1, b2)); + true + } + _ => false } - - false } fn add_to_glob_map(&mut self, id: NodeId, name: Name) { @@ -3307,9 +3302,8 @@ impl<'a> Resolver<'a> { fn report_errors(&self) { let mut reported_spans = FnvHashSet(); - for &(span, name, binding) in &self.ambiguity_errors { + for &(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 875d6745f6b2e..85c03683c8dc7 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, From ff3a6449512e9e6fd1ea455c64cd02a7fa4cc7e2 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 6 Sep 2016 03:47:11 +0000 Subject: [PATCH 4/4] Add struct `AmbiguityError`. --- src/librustc_resolve/lib.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f3044e1847d1b..c5b505fba38e9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -879,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, bool /* true if an error has already been reported */> { match self.kind { @@ -1057,7 +1063,7 @@ pub struct Resolver<'a> { pub maybe_unused_trait_imports: NodeSet, privacy_errors: Vec>, - ambiguity_errors: Vec<(Span, Name, &'a NameBinding<'a>, &'a NameBinding<'a>)>, + ambiguity_errors: Vec>, arenas: &'a ResolverArenas<'a>, dummy_binding: &'a NameBinding<'a>, @@ -1278,7 +1284,8 @@ impl<'a> Resolver<'a> { } NameBindingKind::Import { .. } => false, NameBindingKind::Ambiguity { b1, b2 } => { - self.ambiguity_errors.push((span, name, b1, b2)); + let ambiguity_error = AmbiguityError { span: span, name: name, b1: b1, b2: b2 }; + self.ambiguity_errors.push(ambiguity_error); true } _ => false @@ -3302,7 +3309,7 @@ impl<'a> Resolver<'a> { fn report_errors(&self) { let mut reported_spans = FnvHashSet(); - for &(span, name, b1, b2) in &self.ambiguity_errors { + for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors { if !reported_spans.insert(span) { continue } let msg1 = format!("`{}` could resolve to the name imported here", name); let msg2 = format!("`{}` could also resolve to the name imported here", name);