diff --git a/Cargo.lock b/Cargo.lock
index dab693419a95d..cea17ecc3d409 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4919,6 +4919,7 @@ name = "tidy"
 version = "0.1.0"
 dependencies = [
  "cargo_metadata 0.14.0",
+ "ignore",
  "lazy_static",
  "regex",
  "walkdir",
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 471d78a2922a0..8a6fbaecd6980 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -9,6 +9,7 @@ cargo_metadata = "0.14"
 regex = "1"
 lazy_static = "1"
 walkdir = "2"
+ignore = "0.4.18"
 
 [[bin]]
 name = "rust-tidy"
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index c600f99c2c4bf..b4ee87bb41068 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -2,6 +2,8 @@
 //! - the number of entries in each directory must be less than `ENTRY_LIMIT`
 //! - there are no stray `.stderr` files
 
+use ignore::Walk;
+use ignore::WalkBuilder;
 use std::fs;
 use std::path::Path;
 
@@ -11,34 +13,39 @@ const ROOT_ENTRY_LIMIT: usize = 948;
 const ISSUES_ENTRY_LIMIT: usize = 2117;
 
 fn check_entries(path: &Path, bad: &mut bool) {
-    let dirs = walkdir::WalkDir::new(&path.join("test/ui"))
-        .into_iter()
-        .filter_entry(|e| e.file_type().is_dir());
-    for dir in dirs {
-        if let Ok(dir) = dir {
-            let dir_path = dir.path();
+    for dir in Walk::new(&path.join("test/ui")) {
+        if let Ok(entry) = dir {
+            if entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) {
+                let dir_path = entry.path();
+                // Use special values for these dirs.
+                let is_root = path.join("test/ui") == dir_path;
+                let is_issues_dir = path.join("test/ui/issues") == dir_path;
+                let limit = if is_root {
+                    ROOT_ENTRY_LIMIT
+                } else if is_issues_dir {
+                    ISSUES_ENTRY_LIMIT
+                } else {
+                    ENTRY_LIMIT
+                };
 
-            // Use special values for these dirs.
-            let is_root = path.join("test/ui") == dir_path;
-            let is_issues_dir = path.join("test/ui/issues") == dir_path;
-            let limit = if is_root {
-                ROOT_ENTRY_LIMIT
-            } else if is_issues_dir {
-                ISSUES_ENTRY_LIMIT
-            } else {
-                ENTRY_LIMIT
-            };
+                let count = WalkBuilder::new(&dir_path)
+                    .max_depth(Some(1))
+                    .build()
+                    .into_iter()
+                    .collect::<Vec<_>>()
+                    .len()
+                    - 1; // remove the dir itself
 
-            let count = std::fs::read_dir(dir_path).unwrap().count();
-            if count > limit {
-                tidy_error!(
-                    bad,
-                    "following path contains more than {} entries, \
-                    you should move the test to some relevant subdirectory (current: {}): {}",
-                    limit,
-                    count,
-                    dir_path.display()
-                );
+                if count > limit {
+                    tidy_error!(
+                        bad,
+                        "following path contains more than {} entries, \
+                            you should move the test to some relevant subdirectory (current: {}): {}",
+                        limit,
+                        count,
+                        dir_path.display()
+                    );
+                }
             }
         }
     }