Skip to content

Commit 164039e

Browse files
committed
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 ;-)
1 parent 2db4259 commit 164039e

File tree

6 files changed

+47
-4
lines changed

6 files changed

+47
-4
lines changed

src/rustc/metadata/csearch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num,
7070
result += [(cnum, cm.data, def)];
7171
} else {
7272
if cm.cnum_map.contains_key(def.crate) {
73-
// This reexport is itself a reexport from anther crate
73+
// This reexport is itself a reexport from another crate
7474
let next_cnum = cm.cnum_map.get(def.crate);
7575
let next_cm_data = cstore::get_crate_data(cstore, next_cnum);
7676
result += [(next_cnum, next_cm_data.data, def)];

src/rustc/middle/resolve.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -1667,9 +1667,12 @@ fn ns_for_def(d: def) -> namespace {
16671667
fn lookup_external(e: env, cnum: int, ids: [ident], ns: namespace) ->
16681668
option<def> {
16691669
let mut result = none;
1670+
let mut done = false;
16701671
for csearch::lookup_defs(e.sess.cstore, cnum, ids).each {|d|
16711672
e.ext_map.insert(def_id_of_def(d), ids);
1672-
if ns == ns_for_def(d) { result = some(d); }
1673+
if ns == ns_for_def(d) && !done {
1674+
result = some(d);
1675+
}
16731676
}
16741677
ret result;
16751678
}
@@ -1998,8 +2001,14 @@ fn check_exports(e: @env) {
19982001
}
19992002
}
20002003
}
2001-
found_something |= lookup_glob_any(e, _mod, vi.span, ident,
2002-
export_id);
2004+
/*
2005+
This code previously used bitwise or (|=) but that was wrong,
2006+
because we need or to be lazy here. If something was already
2007+
found, we don't want to call lookup_glob_any (see #2316 for
2008+
what happens if we do)
2009+
*/
2010+
found_something = found_something ||
2011+
lookup_glob_any(e, _mod, vi.span, ident, export_id);
20032012
if !found_something {
20042013
e.sess.span_warn(vi.span,
20052014
#fmt("exported item %s is not defined", ident));

src/test/auxiliary/issue_2316_a.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
enum cat {
2+
tabby, calico, tortoiseshell
3+
}

src/test/auxiliary/issue_2316_b.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use issue_2316_a;
2+
3+
mod cloth {
4+
5+
import issue_2316_a::*;
6+
7+
export calico, gingham, flannel;
8+
export fabric;
9+
10+
enum fabric {
11+
gingham, flannel, calico
12+
}
13+
14+
}
15+
16+

src/test/run-pass/issue-2316-c.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// xfail-fast - check-fast doesn't understand aux-build
2+
// aux-build:issue_2316_a.rs
3+
// aux-build:issue_2316_b.rs
4+
5+
use issue_2316_b;
6+
import issue_2316_b::cloth;
7+
8+
fn main() {
9+
let _c: cloth::fabric = cloth::calico;
10+
}

src/test/run-pass/issue-2316.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use rustc;
2+
import rustc::middle::ty;
3+
fn main() {
4+
let _t: ty::sty = rustc::middle::ty::ty_nil;
5+
}

0 commit comments

Comments
 (0)