Don't re-export a glob-imported ID when the same ID is defined within
a module See the test case I added (issue-2316-c) for a concrete example. issue-2316 also contains the originally reported test case. resolve was using bitwise or instead of logical or when checking exports, resulting in excessively eager evaluation. A one-line fix that took six hours to isolate ;-)
This commit is contained in:
parent
2db4259b35
commit
164039e867
6 changed files with 47 additions and 4 deletions
|
@ -70,7 +70,7 @@ fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num,
|
|||
result += [(cnum, cm.data, def)];
|
||||
} else {
|
||||
if cm.cnum_map.contains_key(def.crate) {
|
||||
// This reexport is itself a reexport from anther crate
|
||||
// This reexport is itself a reexport from another crate
|
||||
let next_cnum = cm.cnum_map.get(def.crate);
|
||||
let next_cm_data = cstore::get_crate_data(cstore, next_cnum);
|
||||
result += [(next_cnum, next_cm_data.data, def)];
|
||||
|
|
|
@ -1667,9 +1667,12 @@ fn ns_for_def(d: def) -> namespace {
|
|||
fn lookup_external(e: env, cnum: int, ids: [ident], ns: namespace) ->
|
||||
option<def> {
|
||||
let mut result = none;
|
||||
let mut done = false;
|
||||
for csearch::lookup_defs(e.sess.cstore, cnum, ids).each {|d|
|
||||
e.ext_map.insert(def_id_of_def(d), ids);
|
||||
if ns == ns_for_def(d) { result = some(d); }
|
||||
if ns == ns_for_def(d) && !done {
|
||||
result = some(d);
|
||||
}
|
||||
}
|
||||
ret result;
|
||||
}
|
||||
|
@ -1998,8 +2001,14 @@ fn check_exports(e: @env) {
|
|||
}
|
||||
}
|
||||
}
|
||||
found_something |= lookup_glob_any(e, _mod, vi.span, ident,
|
||||
export_id);
|
||||
/*
|
||||
This code previously used bitwise or (|=) but that was wrong,
|
||||
because we need or to be lazy here. If something was already
|
||||
found, we don't want to call lookup_glob_any (see #2316 for
|
||||
what happens if we do)
|
||||
*/
|
||||
found_something = found_something ||
|
||||
lookup_glob_any(e, _mod, vi.span, ident, export_id);
|
||||
if !found_something {
|
||||
e.sess.span_warn(vi.span,
|
||||
#fmt("exported item %s is not defined", ident));
|
||||
|
|
3
src/test/auxiliary/issue_2316_a.rs
Normal file
3
src/test/auxiliary/issue_2316_a.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
enum cat {
|
||||
tabby, calico, tortoiseshell
|
||||
}
|
16
src/test/auxiliary/issue_2316_b.rs
Normal file
16
src/test/auxiliary/issue_2316_b.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
use issue_2316_a;
|
||||
|
||||
mod cloth {
|
||||
|
||||
import issue_2316_a::*;
|
||||
|
||||
export calico, gingham, flannel;
|
||||
export fabric;
|
||||
|
||||
enum fabric {
|
||||
gingham, flannel, calico
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
10
src/test/run-pass/issue-2316-c.rs
Normal file
10
src/test/run-pass/issue-2316-c.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// xfail-fast - check-fast doesn't understand aux-build
|
||||
// aux-build:issue_2316_a.rs
|
||||
// aux-build:issue_2316_b.rs
|
||||
|
||||
use issue_2316_b;
|
||||
import issue_2316_b::cloth;
|
||||
|
||||
fn main() {
|
||||
let _c: cloth::fabric = cloth::calico;
|
||||
}
|
5
src/test/run-pass/issue-2316.rs
Normal file
5
src/test/run-pass/issue-2316.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
use rustc;
|
||||
import rustc::middle::ty;
|
||||
fn main() {
|
||||
let _t: ty::sty = rustc::middle::ty::ty_nil;
|
||||
}
|
Loading…
Add table
Reference in a new issue