Track the source of the type_target and value_target separately for ImportResolutions

This commit is contained in:
Alex Crichton 2013-06-09 21:39:15 -07:00
parent 9bcf9119d8
commit b6cccb3d81
2 changed files with 59 additions and 20 deletions

View File

@ -366,25 +366,31 @@ pub struct ImportResolution {
/// The privacy of this `use` directive (whether it's `use` or /// The privacy of this `use` directive (whether it's `use` or
/// `pub use`. /// `pub use`.
privacy: Privacy, privacy: Privacy,
id: node_id,
// The number of outstanding references to this name. When this reaches // The number of outstanding references to this name. When this reaches
// zero, outside modules can count on the targets being correct. Before // zero, outside modules can count on the targets being correct. Before
// then, all bets are off; future imports could override this name. // then, all bets are off; future imports could override this name.
outstanding_references: uint, outstanding_references: uint,
/// The value that this `use` directive names, if there is one. /// The value that this `use` directive names, if there is one.
value_target: Option<Target>, value_target: Option<Target>,
/// The source node of the `use` directive leading to the value target
/// being non-none
value_id: node_id,
/// The type that this `use` directive names, if there is one. /// The type that this `use` directive names, if there is one.
type_target: Option<Target>, type_target: Option<Target>,
/// The source node of the `use` directive leading to the type target
/// being non-none
type_id: node_id,
} }
pub fn ImportResolution(privacy: Privacy, pub fn ImportResolution(privacy: Privacy,
id: node_id) -> ImportResolution { id: node_id) -> ImportResolution {
ImportResolution { ImportResolution {
privacy: privacy, privacy: privacy,
id: id, type_id: id,
value_id: id,
outstanding_references: 0, outstanding_references: 0,
value_target: None, value_target: None,
type_target: None, type_target: None,
@ -399,6 +405,13 @@ impl ImportResolution {
ValueNS => return copy self.value_target ValueNS => return copy self.value_target
} }
} }
fn id(&self, namespace: Namespace) -> node_id {
match namespace {
TypeNS => self.type_id,
ValueNS => self.value_id,
}
}
} }
/// The link from a module up to its nearest parent node. /// The link from a module up to its nearest parent node.
@ -1920,7 +1933,8 @@ impl Resolver {
// the source of this name is different now // the source of this name is different now
resolution.privacy = privacy; resolution.privacy = privacy;
resolution.id = id; resolution.type_id = id;
resolution.value_id = id;
} }
None => { None => {
debug!("(building import directive) creating new"); debug!("(building import directive) creating new");
@ -2118,7 +2132,7 @@ impl Resolver {
containing_module, containing_module,
target, target,
source, source,
import_directive.span); import_directive);
} }
GlobImport => { GlobImport => {
let privacy = import_directive.privacy; let privacy = import_directive.privacy;
@ -2181,7 +2195,7 @@ impl Resolver {
containing_module: @mut Module, containing_module: @mut Module,
target: ident, target: ident,
source: ident, source: ident,
span: span) directive: &ImportDirective)
-> ResolveResult<()> { -> ResolveResult<()> {
debug!("(resolving single import) resolving `%s` = `%s::%s` from \ debug!("(resolving single import) resolving `%s` = `%s::%s` from \
`%s`", `%s`",
@ -2270,9 +2284,10 @@ impl Resolver {
return UnboundResult; return UnboundResult;
} }
Some(target) => { Some(target) => {
this.used_imports.insert(import_resolution.id); let id = import_resolution.id(namespace);
this.used_imports.insert(id);
return BoundResult(target.target_module, return BoundResult(target.target_module,
target.bindings); target.bindings);
} }
} }
} }
@ -2323,8 +2338,10 @@ impl Resolver {
match value_result { match value_result {
BoundResult(target_module, name_bindings) => { BoundResult(target_module, name_bindings) => {
debug!("(resolving single import) found value target");
import_resolution.value_target = import_resolution.value_target =
Some(Target(target_module, name_bindings)); Some(Target(target_module, name_bindings));
import_resolution.value_id = directive.id;
} }
UnboundResult => { /* Continue. */ } UnboundResult => { /* Continue. */ }
UnknownResult => { UnknownResult => {
@ -2333,8 +2350,10 @@ impl Resolver {
} }
match type_result { match type_result {
BoundResult(target_module, name_bindings) => { BoundResult(target_module, name_bindings) => {
debug!("(resolving single import) found type target");
import_resolution.type_target = import_resolution.type_target =
Some(Target(target_module, name_bindings)); Some(Target(target_module, name_bindings));
import_resolution.type_id = directive.id;
} }
UnboundResult => { /* Continue. */ } UnboundResult => { /* Continue. */ }
UnknownResult => { UnknownResult => {
@ -2383,6 +2402,7 @@ impl Resolver {
} }
} }
let span = directive.span;
if resolve_fail { if resolve_fail {
self.session.span_err(span, fmt!("unresolved import: there is no `%s` in `%s`", self.session.span_err(span, fmt!("unresolved import: there is no `%s` in `%s`",
*self.session.str_of(source), *self.session.str_of(source),
@ -2774,7 +2794,7 @@ impl Resolver {
Some(target) => { Some(target) => {
debug!("(resolving item in lexical scope) using \ debug!("(resolving item in lexical scope) using \
import resolution"); import resolution");
self.used_imports.insert(import_resolution.id); self.used_imports.insert(import_resolution.id(namespace));
return Success(copy target); return Success(copy target);
} }
} }
@ -3043,7 +3063,7 @@ impl Resolver {
import_resolution.privacy == Public => { import_resolution.privacy == Public => {
debug!("(resolving name in module) resolved to \ debug!("(resolving name in module) resolved to \
import"); import");
self.used_imports.insert(import_resolution.id); self.used_imports.insert(import_resolution.id(namespace));
return Success(copy target); return Success(copy target);
} }
Some(_) => { Some(_) => {
@ -4525,7 +4545,8 @@ impl Resolver {
namespace)) { namespace)) {
(Some(def), Some(Public)) => { (Some(def), Some(Public)) => {
// Found it. // Found it.
self.used_imports.insert(import_resolution.id); let id = import_resolution.id(namespace);
self.used_imports.insert(id);
return ImportNameDefinition(def); return ImportNameDefinition(def);
} }
(Some(_), _) | (None, _) => { (Some(_), _) | (None, _) => {
@ -5140,7 +5161,7 @@ impl Resolver {
&mut found_traits, &mut found_traits,
trait_def_id, name); trait_def_id, name);
self.used_imports.insert( self.used_imports.insert(
import_resolution.id); import_resolution.type_id);
} }
} }
_ => { _ => {

View File

@ -11,19 +11,37 @@
#[deny(unused_imports)]; #[deny(unused_imports)];
// Regression test for issue #6633 // Regression test for issue #6633
mod issue6633 {
use self::foo::name::name; //~ ERROR: unused import
use self::foo::name;
use foo::name::name; //~ ERROR: unused import pub mod foo {
use foo::name;
pub mod foo {
pub mod name {
pub type a = int;
pub mod name { pub mod name {
pub type a = float; pub type a = int;
pub mod name {
pub type a = float;
}
} }
} }
fn bar() -> name::a { 1 }
} }
fn bar() -> name::a { 1 } // Regression test for issue #6935
mod issue6935 {
use self::a::foo::a::foo;
use self::a::foo; //~ ERROR: unused import
pub mod a {
pub mod foo {
pub mod a {
pub fn foo() {}
}
}
}
fn bar() { foo(); }
}
fn main(){} fn main(){}