about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-12-22 12:41:17 +0100
committerNikita Popov <nikita.ppv@gmail.com>2018-12-22 12:41:17 +0100
commitf93cbf617000673e5ad2fc0fd0eff0c9ea229314 (patch)
tree2203ea7ef4dd841e3f60c9e3872f77e1e87584af
parent9689ada83891f63164bf117af35cc0abc37daaf1 (diff)
downloadrust-f93cbf617000673e5ad2fc0fd0eff0c9ea229314.tar.gz
rust-f93cbf617000673e5ad2fc0fd0eff0c9ea229314.zip
Short-circuit DefIdForest::intersection()
If the forest is already empty, there is no point in intersecting
further.

Also handle the first element separately, so we don't compute an
unnecessary intersection between the full forest and the first
element, which is always equal to the first element.
-rw-r--r--src/librustc/ty/inhabitedness/def_id_forest.rs13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs
index 163263babf8..af2185205a3 100644
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ b/src/librustc/ty/inhabitedness/def_id_forest.rs
@@ -74,10 +74,21 @@ impl<'a, 'gcx, 'tcx> DefIdForest {
                            iter: I) -> DefIdForest
             where I: IntoIterator<Item=DefIdForest>
     {
-        let mut ret = DefIdForest::full(tcx);
+        let mut iter = iter.into_iter();
+        let mut ret = if let Some(first) = iter.next() {
+            first
+        } else {
+            return DefIdForest::full(tcx);
+        };
+
         let mut next_ret = SmallVec::new();
         let mut old_ret: SmallVec<[DefId; 1]> = SmallVec::new();
         for next_forest in iter {
+            // No need to continue if the intersection is already empty.
+            if ret.is_empty() {
+                break;
+            }
+
             for id in ret.root_ids.drain() {
                 if next_forest.contains(tcx, id) {
                     next_ret.push(id);