Skip to content

Commit 6a4483e

Browse files
committed
Fix some bugs with -W unused-imports
1. Don't warn about anything not used in the prelude which is autmoatically injected, accomplished with a test that the span is equal to a dummy span. 2. Don't warn about unused imports from the injected intrinsic module, accomplished by testing against the name of the imported module 3. If anything is used from a glob import, don't warn about the glob import. 4. If an import imports more than one thing, and none of them are used, only issue a warning once Also updated the unused-imports-warn test to have stricter requirements on error messages.
1 parent f1b05ec commit 6a4483e

File tree

2 files changed

+68
-25
lines changed

2 files changed

+68
-25
lines changed

src/librustc/middle/resolve.rs

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -392,17 +392,19 @@ pub struct ImportResolution {
392392
/// The type that this `use` directive names, if there is one.
393393
mut type_target: Option<Target>,
394394
395-
mut used: bool,
395+
/// There exists one state per import statement
396+
state: @mut ImportState,
396397
}
397398
398-
pub fn ImportResolution(privacy: Privacy, span: span) -> ImportResolution {
399+
pub fn ImportResolution(privacy: Privacy, span: span,
400+
state: @mut ImportState) -> ImportResolution {
399401
ImportResolution {
400402
privacy: privacy,
401403
span: span,
402404
outstanding_references: 0,
403405
value_target: None,
404406
type_target: None,
405-
used: false
407+
state: state,
406408
}
407409
}
408410
@@ -415,6 +417,15 @@ pub impl ImportResolution {
415417
}
416418
}
417419
420+
pub struct ImportState {
421+
used: bool,
422+
warned: bool
423+
}
424+
425+
pub fn ImportState() -> ImportState {
426+
ImportState{ used: false, warned: false }
427+
}
428+
418429
/// The link from a module up to its nearest parent node.
419430
pub enum ParentLink {
420431
NoParentLink,
@@ -1415,6 +1426,7 @@ pub impl Resolver {
14151426
14161427
// Build up the import directives.
14171428
let module_ = self.get_module_from_parent(parent);
1429+
let state = @mut ImportState();
14181430
match view_path.node {
14191431
view_path_simple(binding, full_path, ns, _) => {
14201432
let ns = match ns {
@@ -1430,7 +1442,8 @@ pub impl Resolver {
14301442
module_,
14311443
module_path,
14321444
subclass,
1433-
view_path.span);
1445+
view_path.span,
1446+
state);
14341447
}
14351448
view_path_list(_, ref source_idents, _) => {
14361449
for (*source_idents).each |source_ident| {
@@ -1442,15 +1455,17 @@ pub impl Resolver {
14421455
module_,
14431456
module_path,
14441457
subclass,
1445-
view_path.span);
1458+
view_path.span,
1459+
state);
14461460
}
14471461
}
14481462
view_path_glob(_, _) => {
14491463
self.build_import_directive(privacy,
14501464
module_,
14511465
module_path,
14521466
@GlobImport,
1453-
view_path.span);
1467+
view_path.span,
1468+
state);
14541469
}
14551470
}
14561471
}
@@ -1573,7 +1588,8 @@ pub impl Resolver {
15731588
// avoid creating cycles in the
15741589
// module graph.
15751590
1576-
let resolution = @ImportResolution(Public, dummy_sp());
1591+
let resolution = @ImportResolution(Public, dummy_sp(),
1592+
@mut ImportState());
15771593
resolution.outstanding_references = 0;
15781594
15791595
match existing_module.parent_link {
@@ -1826,7 +1842,8 @@ pub impl Resolver {
18261842
module_: @Module,
18271843
module_path: @DVec<ident>,
18281844
subclass: @ImportDirectiveSubclass,
1829-
span: span) {
1845+
span: span,
1846+
state: @mut ImportState) {
18301847
let directive = @ImportDirective(privacy, module_path,
18311848
subclass, span);
18321849
module_.imports.push(directive);
@@ -1850,7 +1867,14 @@ pub impl Resolver {
18501867
}
18511868
None => {
18521869
debug!("(building import directive) creating new");
1853-
let resolution = @ImportResolution(privacy, span);
1870+
let resolution = @ImportResolution(privacy, span,
1871+
state);
1872+
let name = self.idents_to_str(module_path.get());
1873+
// Don't warn about unused intrinsics because they're
1874+
// automatically appended to all files
1875+
if name == ~"intrinsic::rusti" {
1876+
resolution.state.warned = true;
1877+
}
18541878
resolution.outstanding_references = 1;
18551879
module_.import_resolutions.insert(target, resolution);
18561880
}
@@ -2183,7 +2207,7 @@ pub impl Resolver {
21832207
return UnboundResult;
21842208
}
21852209
Some(target) => {
2186-
import_resolution.used = true;
2210+
import_resolution.state.used = true;
21872211
return BoundResult(target.target_module,
21882212
target.bindings);
21892213
}
@@ -2352,7 +2376,7 @@ pub impl Resolver {
23522376
module_result = UnboundResult;
23532377
}
23542378
Some(target) => {
2355-
import_resolution.used = true;
2379+
import_resolution.state.used = true;
23562380
module_result = BoundResult
23572381
(target.target_module,
23582382
target.bindings);
@@ -2419,6 +2443,7 @@ pub impl Resolver {
24192443
// everything it can to the list of import resolutions of the module
24202444
// node.
24212445
debug!("(resolving glob import) resolving %? glob import", privacy);
2446+
let state = @mut ImportState();
24222447
24232448
// We must bail out if the node has unresolved imports of any kind
24242449
// (including globs).
@@ -2445,7 +2470,8 @@ pub impl Resolver {
24452470
// Simple: just copy the old import resolution.
24462471
let new_import_resolution =
24472472
@ImportResolution(privacy,
2448-
target_import_resolution.span);
2473+
target_import_resolution.span,
2474+
state);
24492475
new_import_resolution.value_target =
24502476
copy target_import_resolution.value_target;
24512477
new_import_resolution.type_target =
@@ -2486,7 +2512,8 @@ pub impl Resolver {
24862512
match module_.import_resolutions.find(&ident) {
24872513
None => {
24882514
// Create a new import resolution from this child.
2489-
dest_import_resolution = @ImportResolution(privacy, span);
2515+
dest_import_resolution = @ImportResolution(privacy, span,
2516+
state);
24902517
module_.import_resolutions.insert
24912518
(ident, dest_import_resolution);
24922519
}
@@ -2713,7 +2740,7 @@ pub impl Resolver {
27132740
namespace);
27142741
}
27152742
Some(target) => {
2716-
import_resolution.used = true;
2743+
import_resolution.state.used = true;
27172744
return Success(copy target);
27182745
}
27192746
}
@@ -2962,7 +2989,7 @@ pub impl Resolver {
29622989
Some(target) => {
29632990
debug!("(resolving name in module) resolved to \
29642991
import");
2965-
import_resolution.used = true;
2992+
import_resolution.state.used = true;
29662993
return Success(copy target);
29672994
}
29682995
}
@@ -4560,7 +4587,7 @@ pub impl Resolver {
45604587
namespace)) {
45614588
(Some(def), Some(Public)) => {
45624589
// Found it.
4563-
import_resolution.used = true;
4590+
import_resolution.state.used = true;
45644591
return ImportNameDefinition(def);
45654592
}
45664593
(Some(_), _) | (None, _) => {
@@ -5204,7 +5231,13 @@ pub impl Resolver {
52045231

52055232
fn check_for_unused_imports_in_module(module_: @Module) {
52065233
for module_.import_resolutions.each_value_ref |&import_resolution| {
5207-
if !import_resolution.used {
5234+
// Ignore dummy spans for things like automatically injected
5235+
// imports for the prelude, and also don't warn about the same
5236+
// import statement being unused more than once.
5237+
if !import_resolution.state.used &&
5238+
!import_resolution.state.warned &&
5239+
import_resolution.span != dummy_sp() {
5240+
import_resolution.state.warned = true;
52085241
match self.unused_import_lint_level {
52095242
warn => {
52105243
self.session.span_warn(import_resolution.span,

src/test/compile-fail/unused-imports-warn.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,33 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern:unused import
12-
// compile-flags:-W unused-imports
11+
// compile-flags: -D unused-imports
12+
1313
use cal = bar::c::cc;
1414

15+
use core::either::Right; //~ ERROR unused import
16+
17+
use core::util::*; // shouldn't get errors for not using
18+
// everything imported
19+
20+
// Should only get one error instead of two errors here
21+
use core::option::{Some, None}; //~ ERROR unused import
22+
1523
mod foo {
16-
pub type point = {x: int, y: int};
17-
pub type square = {p: point, h: uint, w: uint};
24+
pub struct Point{x: int, y: int}
25+
pub struct Square{p: Point, h: uint, w: uint}
1826
}
1927

2028
mod bar {
2129
pub mod c {
22-
use foo::point;
23-
use foo::square;
24-
pub fn cc(p: point) -> str { return 2 * (p.x + p.y); }
30+
use foo::Point;
31+
use foo::Square; //~ ERROR unused import
32+
pub fn cc(p: Point) -> int { return 2 * (p.x + p.y); }
2533
}
2634
}
2735

2836
fn main() {
29-
cal({x:3, y:9});
37+
cal(foo::Point{x:3, y:9});
38+
let a = 3;
39+
ignore(a);
3040
}

0 commit comments

Comments
 (0)