From 8de8c679c72d57867714e9627a201de340b64cb6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 17 Jul 2021 18:12:08 +0200 Subject: [PATCH] Fix panic when fuzzy-matching on a `Worktree` that contains no files As part of our work on the deterministic executor, in c4e37dc we fixed a bug that occurred when there were more CPUs than paths to fuzzy-match on. However, that introduced another bug that caused Zed to panic when trying to calculate how many paths should be fuzzy-matched by each available worker thread for worktrees that didn't contain any file. This commit bails out early in `fuzzy::match_paths` if the vector of paths to search is empty. --- zed/src/worktree.rs | 49 +++++++++++++++++++++++++++++++++++++++ zed/src/worktree/fuzzy.rs | 15 +++++++----- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/zed/src/worktree.rs b/zed/src/worktree.rs index 8bbf7b4e41f2ca84b90d5b5493236e019f126e0a..66c71c4e172af039c0054bbe63fa854fb1dfe59e 100644 --- a/zed/src/worktree.rs +++ b/zed/src/worktree.rs @@ -2641,6 +2641,55 @@ mod tests { ); } + #[gpui::test] + async fn test_search_worktree_without_files(cx: gpui::TestAppContext) { + let dir = temp_tree(json!({ + "root": { + "dir1": {}, + "dir2": { + "dir3": {} + } + } + })); + let tree = Worktree::open_local( + dir.path(), + Default::default(), + Arc::new(RealFs), + &mut cx.to_async(), + ) + .await + .unwrap(); + + cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) + .await; + let snapshot = cx.read(|cx| { + let tree = tree.read(cx); + assert_eq!(tree.file_count(), 0); + tree.snapshot() + }); + let results = cx + .read(|cx| { + match_paths( + Some(&snapshot).into_iter(), + "dir", + false, + false, + false, + 10, + Default::default(), + cx.background().clone(), + ) + }) + .await; + assert_eq!( + results + .into_iter() + .map(|result| result.path) + .collect::>>(), + vec![] + ); + } + #[gpui::test] async fn test_save_file(mut cx: gpui::TestAppContext) { let app_state = cx.read(build_app_state); diff --git a/zed/src/worktree/fuzzy.rs b/zed/src/worktree/fuzzy.rs index 776fd2177db59710a64c0ddfd226b0f7846a84bb..0fb406fc98326a01ab353a4812ad3023fe4ebe57 100644 --- a/zed/src/worktree/fuzzy.rs +++ b/zed/src/worktree/fuzzy.rs @@ -64,6 +64,15 @@ pub async fn match_paths<'a, T>( where T: Clone + Send + Iterator + 'a, { + let path_count: usize = if include_ignored { + snapshots.clone().map(Snapshot::file_count).sum() + } else { + snapshots.clone().map(Snapshot::visible_file_count).sum() + }; + if path_count == 0 { + return Vec::new(); + } + let lowercase_query = query.to_lowercase().chars().collect::>(); let query = query.chars().collect::>(); @@ -71,12 +80,6 @@ where let query = &query; let query_chars = CharBag::from(&lowercase_query[..]); - let path_count: usize = if include_ignored { - snapshots.clone().map(Snapshot::file_count).sum() - } else { - snapshots.clone().map(Snapshot::visible_file_count).sum() - }; - let num_cpus = background.num_cpus().min(path_count); let segment_size = (path_count + num_cpus - 1) / num_cpus; let mut segment_results = (0..num_cpus)