Simplifies expandSymbol by mapping symbols' connected components

Uses a quasi-linear, imperative UnionFind (DisjointSet) implementation to
determine the connected components of the graph where nodes are symbols
(initially, allSymbols()) and edges are found through expand().

Absent symbols treatment is essential : not all symbols obtained through
expand() belong to allSymbols().

When we are confident about speed, this should probably be refactored to
remove the previous expandSymbol(), but the current shape of the code
allows easy comparative benchmarking (to get the old version, exercise a
GlobalIndex that mixes in an OverridesInClassHierarchy trait and goes with
the base expandSymbols).

This should not be merged without reviewer's speed benchmarks.
Fixes #1001295.