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.
This commit is contained in:
parent
f1b05ece93
commit
6a4483ec7a
2 changed files with 68 additions and 25 deletions
|
|
@ -392,17 +392,19 @@ pub struct ImportResolution {
|
|||
/// The type that this `use` directive names, if there is one.
|
||||
mut type_target: Option<Target>,
|
||||
|
||||
mut used: bool,
|
||||
/// There exists one state per import statement
|
||||
state: @mut ImportState,
|
||||
}
|
||||
|
||||
pub fn ImportResolution(privacy: Privacy, span: span) -> ImportResolution {
|
||||
pub fn ImportResolution(privacy: Privacy, span: span,
|
||||
state: @mut ImportState) -> ImportResolution {
|
||||
ImportResolution {
|
||||
privacy: privacy,
|
||||
span: span,
|
||||
outstanding_references: 0,
|
||||
value_target: None,
|
||||
type_target: None,
|
||||
used: false
|
||||
state: state,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -415,6 +417,15 @@ pub impl ImportResolution {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ImportState {
|
||||
used: bool,
|
||||
warned: bool
|
||||
}
|
||||
|
||||
pub fn ImportState() -> ImportState {
|
||||
ImportState{ used: false, warned: false }
|
||||
}
|
||||
|
||||
/// The link from a module up to its nearest parent node.
|
||||
pub enum ParentLink {
|
||||
NoParentLink,
|
||||
|
|
@ -1415,6 +1426,7 @@ pub impl Resolver {
|
|||
|
||||
// Build up the import directives.
|
||||
let module_ = self.get_module_from_parent(parent);
|
||||
let state = @mut ImportState();
|
||||
match view_path.node {
|
||||
view_path_simple(binding, full_path, ns, _) => {
|
||||
let ns = match ns {
|
||||
|
|
@ -1430,7 +1442,8 @@ pub impl Resolver {
|
|||
module_,
|
||||
module_path,
|
||||
subclass,
|
||||
view_path.span);
|
||||
view_path.span,
|
||||
state);
|
||||
}
|
||||
view_path_list(_, ref source_idents, _) => {
|
||||
for (*source_idents).each |source_ident| {
|
||||
|
|
@ -1442,7 +1455,8 @@ pub impl Resolver {
|
|||
module_,
|
||||
module_path,
|
||||
subclass,
|
||||
view_path.span);
|
||||
view_path.span,
|
||||
state);
|
||||
}
|
||||
}
|
||||
view_path_glob(_, _) => {
|
||||
|
|
@ -1450,7 +1464,8 @@ pub impl Resolver {
|
|||
module_,
|
||||
module_path,
|
||||
@GlobImport,
|
||||
view_path.span);
|
||||
view_path.span,
|
||||
state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1573,7 +1588,8 @@ pub impl Resolver {
|
|||
// avoid creating cycles in the
|
||||
// module graph.
|
||||
|
||||
let resolution = @ImportResolution(Public, dummy_sp());
|
||||
let resolution = @ImportResolution(Public, dummy_sp(),
|
||||
@mut ImportState());
|
||||
resolution.outstanding_references = 0;
|
||||
|
||||
match existing_module.parent_link {
|
||||
|
|
@ -1826,7 +1842,8 @@ pub impl Resolver {
|
|||
module_: @Module,
|
||||
module_path: @DVec<ident>,
|
||||
subclass: @ImportDirectiveSubclass,
|
||||
span: span) {
|
||||
span: span,
|
||||
state: @mut ImportState) {
|
||||
let directive = @ImportDirective(privacy, module_path,
|
||||
subclass, span);
|
||||
module_.imports.push(directive);
|
||||
|
|
@ -1850,7 +1867,14 @@ pub impl Resolver {
|
|||
}
|
||||
None => {
|
||||
debug!("(building import directive) creating new");
|
||||
let resolution = @ImportResolution(privacy, span);
|
||||
let resolution = @ImportResolution(privacy, span,
|
||||
state);
|
||||
let name = self.idents_to_str(module_path.get());
|
||||
// Don't warn about unused intrinsics because they're
|
||||
// automatically appended to all files
|
||||
if name == ~"intrinsic::rusti" {
|
||||
resolution.state.warned = true;
|
||||
}
|
||||
resolution.outstanding_references = 1;
|
||||
module_.import_resolutions.insert(target, resolution);
|
||||
}
|
||||
|
|
@ -2183,7 +2207,7 @@ pub impl Resolver {
|
|||
return UnboundResult;
|
||||
}
|
||||
Some(target) => {
|
||||
import_resolution.used = true;
|
||||
import_resolution.state.used = true;
|
||||
return BoundResult(target.target_module,
|
||||
target.bindings);
|
||||
}
|
||||
|
|
@ -2352,7 +2376,7 @@ pub impl Resolver {
|
|||
module_result = UnboundResult;
|
||||
}
|
||||
Some(target) => {
|
||||
import_resolution.used = true;
|
||||
import_resolution.state.used = true;
|
||||
module_result = BoundResult
|
||||
(target.target_module,
|
||||
target.bindings);
|
||||
|
|
@ -2419,6 +2443,7 @@ pub impl Resolver {
|
|||
// everything it can to the list of import resolutions of the module
|
||||
// node.
|
||||
debug!("(resolving glob import) resolving %? glob import", privacy);
|
||||
let state = @mut ImportState();
|
||||
|
||||
// We must bail out if the node has unresolved imports of any kind
|
||||
// (including globs).
|
||||
|
|
@ -2445,7 +2470,8 @@ pub impl Resolver {
|
|||
// Simple: just copy the old import resolution.
|
||||
let new_import_resolution =
|
||||
@ImportResolution(privacy,
|
||||
target_import_resolution.span);
|
||||
target_import_resolution.span,
|
||||
state);
|
||||
new_import_resolution.value_target =
|
||||
copy target_import_resolution.value_target;
|
||||
new_import_resolution.type_target =
|
||||
|
|
@ -2486,7 +2512,8 @@ pub impl Resolver {
|
|||
match module_.import_resolutions.find(&ident) {
|
||||
None => {
|
||||
// Create a new import resolution from this child.
|
||||
dest_import_resolution = @ImportResolution(privacy, span);
|
||||
dest_import_resolution = @ImportResolution(privacy, span,
|
||||
state);
|
||||
module_.import_resolutions.insert
|
||||
(ident, dest_import_resolution);
|
||||
}
|
||||
|
|
@ -2713,7 +2740,7 @@ pub impl Resolver {
|
|||
namespace);
|
||||
}
|
||||
Some(target) => {
|
||||
import_resolution.used = true;
|
||||
import_resolution.state.used = true;
|
||||
return Success(copy target);
|
||||
}
|
||||
}
|
||||
|
|
@ -2962,7 +2989,7 @@ pub impl Resolver {
|
|||
Some(target) => {
|
||||
debug!("(resolving name in module) resolved to \
|
||||
import");
|
||||
import_resolution.used = true;
|
||||
import_resolution.state.used = true;
|
||||
return Success(copy target);
|
||||
}
|
||||
}
|
||||
|
|
@ -4560,7 +4587,7 @@ pub impl Resolver {
|
|||
namespace)) {
|
||||
(Some(def), Some(Public)) => {
|
||||
// Found it.
|
||||
import_resolution.used = true;
|
||||
import_resolution.state.used = true;
|
||||
return ImportNameDefinition(def);
|
||||
}
|
||||
(Some(_), _) | (None, _) => {
|
||||
|
|
@ -5204,7 +5231,13 @@ pub impl Resolver {
|
|||
|
||||
fn check_for_unused_imports_in_module(module_: @Module) {
|
||||
for module_.import_resolutions.each_value_ref |&import_resolution| {
|
||||
if !import_resolution.used {
|
||||
// Ignore dummy spans for things like automatically injected
|
||||
// imports for the prelude, and also don't warn about the same
|
||||
// import statement being unused more than once.
|
||||
if !import_resolution.state.used &&
|
||||
!import_resolution.state.warned &&
|
||||
import_resolution.span != dummy_sp() {
|
||||
import_resolution.state.warned = true;
|
||||
match self.unused_import_lint_level {
|
||||
warn => {
|
||||
self.session.span_warn(import_resolution.span,
|
||||
|
|
|
|||
|
|
@ -8,23 +8,33 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:unused import
|
||||
// compile-flags:-W unused-imports
|
||||
// compile-flags: -D unused-imports
|
||||
|
||||
use cal = bar::c::cc;
|
||||
|
||||
use core::either::Right; //~ ERROR unused import
|
||||
|
||||
use core::util::*; // shouldn't get errors for not using
|
||||
// everything imported
|
||||
|
||||
// Should only get one error instead of two errors here
|
||||
use core::option::{Some, None}; //~ ERROR unused import
|
||||
|
||||
mod foo {
|
||||
pub type point = {x: int, y: int};
|
||||
pub type square = {p: point, h: uint, w: uint};
|
||||
pub struct Point{x: int, y: int}
|
||||
pub struct Square{p: Point, h: uint, w: uint}
|
||||
}
|
||||
|
||||
mod bar {
|
||||
pub mod c {
|
||||
use foo::point;
|
||||
use foo::square;
|
||||
pub fn cc(p: point) -> str { return 2 * (p.x + p.y); }
|
||||
use foo::Point;
|
||||
use foo::Square; //~ ERROR unused import
|
||||
pub fn cc(p: Point) -> int { return 2 * (p.x + p.y); }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
cal({x:3, y:9});
|
||||
cal(foo::Point{x:3, y:9});
|
||||
let a = 3;
|
||||
ignore(a);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue