From 91bfbb968751ae8441ebccefed7cd63ca00b43dd Mon Sep 17 00:00:00 2001
From: Vytautas Astrauskas <vastrauskas@gmail.com>
Date: Mon, 10 Dec 2018 15:59:55 +0100
Subject: [PATCH 1/3] Use compiletest timestamp to check if the tests should be
 rerun.

---
 src/tools/compiletest/src/main.rs | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 9aefd15765df6..68db2402213d8 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -682,6 +682,20 @@ fn stamp(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> Path
     output_base_dir(config, testpaths, revision).join("stamp")
 }
 
+/// Walk the directory at `path` and collect timestamps of all files into `inputs`.
+fn collect_timestamps(path: &PathBuf, inputs: &mut Vec<FileTime>) {
+    let mut entries = path.read_dir().unwrap().collect::<Vec<_>>();
+    while let Some(entry) = entries.pop() {
+        let entry = entry.unwrap();
+        let path = entry.path();
+        if entry.metadata().unwrap().is_file() {
+            inputs.push(mtime(&path));
+        } else {
+            entries.extend(path.read_dir().unwrap());
+        }
+    }
+}
+
 fn up_to_date(
     config: &Config,
     testpaths: &TestPaths,
@@ -725,16 +739,7 @@ fn up_to_date(
     for pretty_printer_file in &pretty_printer_files {
         inputs.push(mtime(&rust_src_dir.join(pretty_printer_file)));
     }
-    let mut entries = config.run_lib_path.read_dir().unwrap().collect::<Vec<_>>();
-    while let Some(entry) = entries.pop() {
-        let entry = entry.unwrap();
-        let path = entry.path();
-        if entry.metadata().unwrap().is_file() {
-            inputs.push(mtime(&path));
-        } else {
-            entries.extend(path.read_dir().unwrap());
-        }
-    }
+    collect_timestamps(&config.run_lib_path, &mut inputs);
     if let Some(ref rustdoc_path) = config.rustdoc_path {
         inputs.push(mtime(&rustdoc_path));
         inputs.push(mtime(&rust_src_dir.join("src/etc/htmldocck.py")));
@@ -746,6 +751,9 @@ fn up_to_date(
         inputs.push(mtime(path));
     }
 
+    // Compiletest itself.
+    collect_timestamps(&rust_src_dir.join("src/tools/compiletest/"), &mut inputs);
+
     inputs.iter().any(|input| *input > stamp)
 }
 

From ecf8df5b7e5b65cb55409fce80dd58ebebd6c846 Mon Sep 17 00:00:00 2001
From: Vytautas Astrauskas <vastrauskas@gmail.com>
Date: Thu, 13 Dec 2018 16:23:53 +0100
Subject: [PATCH 2/3] Address the pull request review comments.

---
 src/tools/compiletest/Cargo.toml  |  1 +
 src/tools/compiletest/src/main.rs | 25 +++++++++++--------------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 0ee3143935897..edf4aeab1c70f 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -15,6 +15,7 @@ serde_json = "1.0"
 serde_derive = "1.0"
 rustfix = "0.4.1"
 lazy_static = "1.0"
+walkdir = "2"
 
 [target.'cfg(unix)'.dependencies]
 libc = "0.2"
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 68db2402213d8..a532e900ea3e0 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -28,6 +28,7 @@ extern crate serde_derive;
 extern crate serde_json;
 extern crate test;
 extern crate rustfix;
+extern crate walkdir;
 
 use common::CompareMode;
 use common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
@@ -43,6 +44,7 @@ use std::path::{Path, PathBuf};
 use std::process::Command;
 use test::ColorConfig;
 use util::logv;
+use walkdir::WalkDir;
 
 use self::header::{EarlyProps, Ignore};
 
@@ -682,18 +684,13 @@ fn stamp(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> Path
     output_base_dir(config, testpaths, revision).join("stamp")
 }
 
-/// Walk the directory at `path` and collect timestamps of all files into `inputs`.
-fn collect_timestamps(path: &PathBuf, inputs: &mut Vec<FileTime>) {
-    let mut entries = path.read_dir().unwrap().collect::<Vec<_>>();
-    while let Some(entry) = entries.pop() {
-        let entry = entry.unwrap();
-        let path = entry.path();
-        if entry.metadata().unwrap().is_file() {
-            inputs.push(mtime(&path));
-        } else {
-            entries.extend(path.read_dir().unwrap());
-        }
-    }
+/// Return an iterator over timestamps of files in the directory at `path`.
+fn collect_timestamps(path: &PathBuf) -> impl Iterator<Item=FileTime> {
+    WalkDir::new(path)
+        .into_iter()
+        .map(|entry| entry.unwrap())
+        .filter(|entry| entry.metadata().unwrap().is_file())
+        .map(|entry| mtime(entry.path()))
 }
 
 fn up_to_date(
@@ -739,7 +736,7 @@ fn up_to_date(
     for pretty_printer_file in &pretty_printer_files {
         inputs.push(mtime(&rust_src_dir.join(pretty_printer_file)));
     }
-    collect_timestamps(&config.run_lib_path, &mut inputs);
+    inputs.extend(collect_timestamps(&config.run_lib_path));
     if let Some(ref rustdoc_path) = config.rustdoc_path {
         inputs.push(mtime(&rustdoc_path));
         inputs.push(mtime(&rust_src_dir.join("src/etc/htmldocck.py")));
@@ -752,7 +749,7 @@ fn up_to_date(
     }
 
     // Compiletest itself.
-    collect_timestamps(&rust_src_dir.join("src/tools/compiletest/"), &mut inputs);
+    inputs.extend(collect_timestamps(&rust_src_dir.join("src/tools/compiletest/")));
 
     inputs.iter().any(|input| *input > stamp)
 }

From d966e57407fc2c09ce3345b7d797633aa4046912 Mon Sep 17 00:00:00 2001
From: Vytautas Astrauskas <vastrauskas@gmail.com>
Date: Mon, 17 Dec 2018 13:40:40 +0100
Subject: [PATCH 3/3] Fix Cargo.lock.

---
 Cargo.lock | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Cargo.lock b/Cargo.lock
index 7e03474565d85..365d14c579bdb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -431,6 +431,7 @@ dependencies = [
  "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]