Skip to content

Commit 5114f8a

Browse files
authored
Auto merge of #36276 - jseyfried:fix_unused, r=nrc
resolve: Fix unused import false positive with `item_like_imports` Fixes #36249. r? @nrc
2 parents 1d04201 + ff3a644 commit 5114f8a

File tree

3 files changed

+63
-22
lines changed

3 files changed

+63
-22
lines changed

src/librustc_resolve/lib.rs

+24-22
Original file line numberDiff line numberDiff line change
@@ -871,16 +871,23 @@ enum NameBindingKind<'a> {
871871
Import {
872872
binding: &'a NameBinding<'a>,
873873
directive: &'a ImportDirective<'a>,
874+
used: Cell<bool>,
874875
},
875876
Ambiguity {
876877
b1: &'a NameBinding<'a>,
877878
b2: &'a NameBinding<'a>,
878879
}
879880
}
880881

881-
#[derive(Clone, Debug)]
882882
struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>);
883883

884+
struct AmbiguityError<'a> {
885+
span: Span,
886+
name: Name,
887+
b1: &'a NameBinding<'a>,
888+
b2: &'a NameBinding<'a>,
889+
}
890+
884891
impl<'a> NameBinding<'a> {
885892
fn module(&self) -> Result<Module<'a>, bool /* true if an error has already been reported */> {
886893
match self.kind {
@@ -938,14 +945,6 @@ impl<'a> NameBinding<'a> {
938945
_ => true,
939946
}
940947
}
941-
942-
fn ambiguity(&self) -> Option<(&'a NameBinding<'a>, &'a NameBinding<'a>)> {
943-
match self.kind {
944-
NameBindingKind::Ambiguity { b1, b2 } => Some((b1, b2)),
945-
NameBindingKind::Import { binding, .. } => binding.ambiguity(),
946-
_ => None,
947-
}
948-
}
949948
}
950949

951950
/// Interns the names of the primitive types.
@@ -1064,7 +1063,7 @@ pub struct Resolver<'a> {
10641063
pub maybe_unused_trait_imports: NodeSet,
10651064

10661065
privacy_errors: Vec<PrivacyError<'a>>,
1067-
ambiguity_errors: Vec<(Span, Name, &'a NameBinding<'a>)>,
1066+
ambiguity_errors: Vec<AmbiguityError<'a>>,
10681067

10691068
arenas: &'a ResolverArenas<'a>,
10701069
dummy_binding: &'a NameBinding<'a>,
@@ -1276,17 +1275,21 @@ impl<'a> Resolver<'a> {
12761275
self.used_crates.insert(krate);
12771276
}
12781277

1279-
if let NameBindingKind::Import { directive, .. } = binding.kind {
1280-
self.used_imports.insert((directive.id, ns));
1281-
self.add_to_glob_map(directive.id, name);
1282-
}
1283-
1284-
if binding.ambiguity().is_some() {
1285-
self.ambiguity_errors.push((span, name, binding));
1286-
return true;
1278+
match binding.kind {
1279+
NameBindingKind::Import { directive, binding, ref used } if !used.get() => {
1280+
used.set(true);
1281+
self.used_imports.insert((directive.id, ns));
1282+
self.add_to_glob_map(directive.id, name);
1283+
self.record_use(name, ns, binding, span)
1284+
}
1285+
NameBindingKind::Import { .. } => false,
1286+
NameBindingKind::Ambiguity { b1, b2 } => {
1287+
let ambiguity_error = AmbiguityError { span: span, name: name, b1: b1, b2: b2 };
1288+
self.ambiguity_errors.push(ambiguity_error);
1289+
true
1290+
}
1291+
_ => false
12871292
}
1288-
1289-
false
12901293
}
12911294

12921295
fn add_to_glob_map(&mut self, id: NodeId, name: Name) {
@@ -3306,9 +3309,8 @@ impl<'a> Resolver<'a> {
33063309
fn report_errors(&self) {
33073310
let mut reported_spans = FnvHashSet();
33083311

3309-
for &(span, name, binding) in &self.ambiguity_errors {
3312+
for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors {
33103313
if !reported_spans.insert(span) { continue }
3311-
let (b1, b2) = binding.ambiguity().unwrap();
33123314
let msg1 = format!("`{}` could resolve to the name imported here", name);
33133315
let msg2 = format!("`{}` could also resolve to the name imported here", name);
33143316
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))

src/librustc_resolve/resolve_imports.rs

+1
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ impl<'a> Resolver<'a> {
308308
kind: NameBindingKind::Import {
309309
binding: binding,
310310
directive: directive,
311+
used: Cell::new(false),
311312
},
312313
span: directive.span,
313314
vis: vis,
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(pub_restricted, item_like_imports)]
12+
#![deny(unused)]
13+
14+
mod foo {
15+
fn f() {}
16+
17+
mod m1 {
18+
pub(super) use super::f; //~ ERROR unused
19+
}
20+
21+
mod m2 {
22+
#[allow(unused)]
23+
use super::m1::*; // (despite this glob import)
24+
}
25+
26+
mod m3 {
27+
pub(super) use super::f; // Check that this is counted as used (c.f. #36249).
28+
}
29+
30+
pub mod m4 {
31+
use super::m3::*;
32+
pub fn g() { f(); }
33+
}
34+
}
35+
36+
fn main() {
37+
foo::m4::g();
38+
}

0 commit comments

Comments
 (0)