Auto merge of #36276 - jseyfried:fix_unused, r=nrc

resolve: Fix unused import false positive with `item_like_imports`

Fixes #36249.
r? @nrc
This commit is contained in:
bors 2016-09-06 01:44:13 -07:00 committed by GitHub
commit 5114f8a29b
3 changed files with 63 additions and 22 deletions

View File

@ -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);
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
}
if binding.ambiguity().is_some() {
self.ambiguity_errors.push((span, name, binding));
return true;
}
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))

View File

@ -308,6 +308,7 @@ impl<'a> Resolver<'a> {
kind: NameBindingKind::Import {
binding: binding,
directive: directive,
used: Cell::new(false),
},
span: directive.span,
vis: vis,

View File

@ -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();
}