Skip to content

Commit

Permalink
Auto merge of #36276 - jseyfried:fix_unused, r=nrc
Browse files Browse the repository at this point in the history
resolve: Fix unused import false positive with `item_like_imports`

Fixes #36249.
r? @nrc
  • Loading branch information
bors committed Sep 6, 2016
2 parents 1d04201 + ff3a644 commit 5114f8a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 22 deletions.
46 changes: 24 additions & 22 deletions src/librustc_resolve/lib.rs
Expand Up @@ -871,16 +871,23 @@ enum NameBindingKind<'a> {
Import {
binding: &'a NameBinding<'a>,
directive: &'a ImportDirective<'a>,
used: Cell<bool>,
},
Ambiguity {
b1: &'a NameBinding<'a>,
b2: &'a NameBinding<'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 {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions src/librustc_resolve/resolve_imports.rs
Expand Up @@ -308,6 +308,7 @@ impl<'a> Resolver<'a> {
kind: NameBindingKind::Import {
binding: binding,
directive: directive,
used: Cell::new(false),
},
span: directive.span,
vis: vis,
Expand Down
38 changes: 38 additions & 0 deletions 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();
}

0 comments on commit 5114f8a

Please sign in to comment.