Skip to content

Commit 8cb17ad

Browse files
committed
Merge pull request #4668 from ILyoan/i2673
fix #2673: avoid visiting the same crate twice
2 parents 226cd68 + 8ec36d7 commit 8cb17ad

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

src/rt/rust_crate_map.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
#include "rust_crate_map.h"
12+
#include <set>
1213

1314
void iter_module_map(const mod_entry* map,
1415
void (*fn)(const mod_entry* entry, void *cookie),
@@ -20,18 +21,27 @@ void iter_module_map(const mod_entry* map,
2021

2122
void iter_crate_map(const cratemap* map,
2223
void (*fn)(const mod_entry* map, void *cookie),
23-
void *cookie) {
24-
// First iterate this crate
25-
iter_module_map(map->entries(), fn, cookie);
26-
// Then recurse on linked crates
27-
// FIXME (#2673) this does double work in diamond-shaped deps. could
28-
// keep a set of visited addresses, if it turns out to be actually
29-
// slow
30-
for (cratemap::iterator i = map->begin(), e = map->end(); i != e; ++i) {
31-
iter_crate_map(*i, fn, cookie);
24+
void *cookie,
25+
std::set<const cratemap*>& visited) {
26+
if (visited.find(map) == visited.end()) {
27+
// Mark this crate visited
28+
visited.insert(map);
29+
// First iterate this crate
30+
iter_module_map(map->entries(), fn, cookie);
31+
// Then recurse on linked crates
32+
for (cratemap::iterator i = map->begin(),
33+
e = map->end(); i != e; ++i) {
34+
iter_crate_map(*i, fn, cookie, visited);
35+
}
3236
}
3337
}
3438

39+
void iter_crate_map(const cratemap* map,
40+
void (*fn)(const mod_entry* map, void *cookie),
41+
void *cookie) {
42+
std::set<const cratemap*> visited;
43+
iter_crate_map(map, fn, cookie, visited);
44+
}
3545
//
3646
// Local Variables:
3747
// mode: C++

0 commit comments

Comments
 (0)