diff --git a/Cargo.toml b/Cargo.toml index a2de4aaaed..6218e8dbb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -904,6 +904,7 @@ ok_expect = "warn" owned_cow = "warn" print_literal = "warn" print_with_newline = "warn" +println_empty_string = "warn" ptr_eq = "warn" question_mark = "warn" redundant_closure = "warn" @@ -924,7 +925,9 @@ unneeded_struct_pattern = "warn" unsafe_removed_from_name = "warn" unused_unit = "warn" unusual_byte_groupings = "warn" +while_let_on_iterator = "warn" write_literal = "warn" +write_with_newline = "warn" writeln_empty_string = "warn" wrong_self_convention = "warn" zero_ptr = "warn" diff --git a/crates/agent/src/context.rs b/crates/agent/src/context.rs index 9bb8fc0eae..a94a933d86 100644 --- a/crates/agent/src/context.rs +++ b/crates/agent/src/context.rs @@ -362,7 +362,7 @@ impl Display for DirectoryContext { let mut is_first = true; for descendant in &self.descendants { if !is_first { - write!(f, "\n")?; + writeln!(f)?; } else { is_first = false; } @@ -650,7 +650,7 @@ impl TextThreadContextHandle { impl Display for TextThreadContext { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { // TODO: escape title? - write!(f, "\n", self.title)?; + writeln!(f, "", self.title)?; write!(f, "{}", self.text.trim())?; write!(f, "\n") } @@ -716,7 +716,7 @@ impl RulesContextHandle { impl Display for RulesContext { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if let Some(title) = &self.title { - write!(f, "Rules title: {}\n", title)?; + writeln!(f, "Rules title: {}", title)?; } let code_block = MarkdownCodeBlock { tag: "", diff --git a/crates/agent2/src/thread.rs b/crates/agent2/src/thread.rs index f407ee7de5..01c9ab03ba 100644 --- a/crates/agent2/src/thread.rs +++ b/crates/agent2/src/thread.rs @@ -163,7 +163,7 @@ impl UserMessage { if !content.is_empty() { let _ = write!(&mut markdown, "{}\n\n{}\n", uri.as_link(), content); } else { - let _ = write!(&mut markdown, "{}\n", uri.as_link()); + let _ = writeln!(&mut markdown, "{}", uri.as_link()); } } } diff --git a/crates/buffer_diff/src/buffer_diff.rs b/crates/buffer_diff/src/buffer_diff.rs index bef0c5cfc3..10b59d0ba2 100644 --- a/crates/buffer_diff/src/buffer_diff.rs +++ b/crates/buffer_diff/src/buffer_diff.rs @@ -2024,8 +2024,8 @@ mod tests { fn gen_working_copy(rng: &mut StdRng, head: &str) -> String { let mut old_lines = { let mut old_lines = Vec::new(); - let mut old_lines_iter = head.lines(); - while let Some(line) = old_lines_iter.next() { + let old_lines_iter = head.lines(); + for line in old_lines_iter { assert!(!line.ends_with("\n")); old_lines.push(line.to_owned()); } diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 1e0cdc34ac..e32a4e45db 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -3183,9 +3183,9 @@ mod tests { // so we special case row 0 to assume a leading '\n'. // // Linehood is the birthright of strings. - let mut input_text_lines = input_text.split('\n').enumerate().peekable(); + let input_text_lines = input_text.split('\n').enumerate().peekable(); let mut block_row = 0; - while let Some((wrap_row, input_line)) = input_text_lines.next() { + for (wrap_row, input_line) in input_text_lines { let wrap_row = wrap_row as u32; let multibuffer_row = wraps_snapshot .to_point(WrapPoint::new(wrap_row, 0), Bias::Left) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 2136d5f4b3..45a90b843b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -11021,7 +11021,7 @@ impl Editor { let mut col = 0; let mut changed = false; - while let Some(ch) = chars.next() { + for ch in chars.by_ref() { match ch { ' ' => { reindented_line.push(' '); @@ -11077,7 +11077,7 @@ impl Editor { let mut first_non_indent_char = None; let mut changed = false; - while let Some(ch) = chars.next() { + for ch in chars.by_ref() { match ch { ' ' => { // Keep track of spaces. Append \t when we reach tab_size diff --git a/crates/editor/src/indent_guides.rs b/crates/editor/src/indent_guides.rs index a1de2b604b..23717eeb15 100644 --- a/crates/editor/src/indent_guides.rs +++ b/crates/editor/src/indent_guides.rs @@ -164,8 +164,8 @@ pub fn indent_guides_in_range( let end_anchor = snapshot.buffer_snapshot.anchor_after(end_offset); let mut fold_ranges = Vec::>::new(); - let mut folds = snapshot.folds_in_range(start_offset..end_offset).peekable(); - while let Some(fold) = folds.next() { + let folds = snapshot.folds_in_range(start_offset..end_offset).peekable(); + for fold in folds { let start = fold.range.start.to_point(&snapshot.buffer_snapshot); let end = fold.range.end.to_point(&snapshot.buffer_snapshot); if let Some(last_range) = fold_ranges.last_mut() diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 62889c638f..afc5767de0 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -103,9 +103,9 @@ impl FollowableItem for Editor { multibuffer = MultiBuffer::new(project.read(cx).capability()); let mut sorted_excerpts = state.excerpts.clone(); sorted_excerpts.sort_by_key(|e| e.id); - let mut sorted_excerpts = sorted_excerpts.into_iter().peekable(); + let sorted_excerpts = sorted_excerpts.into_iter().peekable(); - while let Some(excerpt) = sorted_excerpts.next() { + for excerpt in sorted_excerpts { let Ok(buffer_id) = BufferId::new(excerpt.buffer_id) else { continue; }; diff --git a/crates/eval/src/eval.rs b/crates/eval/src/eval.rs index c5a072eea1..9e0504abca 100644 --- a/crates/eval/src/eval.rs +++ b/crates/eval/src/eval.rs @@ -706,7 +706,7 @@ fn print_report( println!("Average thread score: {average_thread_score}%"); } - println!(""); + println!(); print_h2("CUMULATIVE TOOL METRICS"); println!("{}", cumulative_tool_metrics); diff --git a/crates/eval/src/instance.rs b/crates/eval/src/instance.rs index 074cb121d3..c6e4e0b6ec 100644 --- a/crates/eval/src/instance.rs +++ b/crates/eval/src/instance.rs @@ -913,9 +913,9 @@ impl RequestMarkdown { for tool in &request.tools { write!(&mut tools, "# {}\n\n", tool.name).unwrap(); write!(&mut tools, "{}\n\n", tool.description).unwrap(); - write!( + writeln!( &mut tools, - "{}\n", + "{}", MarkdownCodeBlock { tag: "json", text: &format!("{:#}", tool.input_schema) diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index 9c125d2c47..fd12dafa98 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -916,7 +916,7 @@ impl GitRepository for RealGitRepository { .context("no stdin for git cat-file subprocess")?; let mut stdin = BufWriter::new(stdin); for rev in &revs { - write!(&mut stdin, "{rev}\n")?; + writeln!(&mut stdin, "{rev}")?; } stdin.flush()?; drop(stdin); diff --git a/crates/language/src/text_diff.rs b/crates/language/src/text_diff.rs index cb2242a6b1..11d8a070d2 100644 --- a/crates/language/src/text_diff.rs +++ b/crates/language/src/text_diff.rs @@ -186,7 +186,7 @@ fn tokenize(text: &str, language_scope: Option) -> impl Iterator< let mut prev = None; let mut start_ix = 0; iter::from_fn(move || { - while let Some((ix, c)) = chars.next() { + for (ix, c) in chars.by_ref() { let mut token = None; let kind = classifier.kind(c); if let Some((prev_char, prev_kind)) = prev diff --git a/crates/multi_buffer/src/multi_buffer_tests.rs b/crates/multi_buffer/src/multi_buffer_tests.rs index 598ee0f9cb..61b4b0520f 100644 --- a/crates/multi_buffer/src/multi_buffer_tests.rs +++ b/crates/multi_buffer/src/multi_buffer_tests.rs @@ -2250,11 +2250,11 @@ impl ReferenceMultibuffer { let base_buffer = diff.base_text(); let mut offset = buffer_range.start; - let mut hunks = diff + let hunks = diff .hunks_intersecting_range(excerpt.range.clone(), buffer, cx) .peekable(); - while let Some(hunk) = hunks.next() { + for hunk in hunks { // Ignore hunks that are outside the excerpt range. let mut hunk_range = hunk.buffer_range.to_offset(buffer); diff --git a/crates/project/src/git_store/git_traversal.rs b/crates/project/src/git_store/git_traversal.rs index 9eadaeac82..eee492e482 100644 --- a/crates/project/src/git_store/git_traversal.rs +++ b/crates/project/src/git_store/git_traversal.rs @@ -42,8 +42,8 @@ impl<'a> GitTraversal<'a> { // other_repo/ // .git/ // our_query.txt - let mut query = path.ancestors(); - while let Some(query) = query.next() { + let query = path.ancestors(); + for query in query { let (_, snapshot) = self .repo_root_to_snapshot .range(Path::new("")..=query) diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 1b46117897..0b58009f37 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -13149,10 +13149,10 @@ fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) { let mut offset_map = vec![0; label.text.len() + 1]; let mut last_char_was_space = false; let mut new_idx = 0; - let mut chars = label.text.char_indices().fuse(); + let chars = label.text.char_indices().fuse(); let mut newlines_removed = false; - while let Some((idx, c)) = chars.next() { + for (idx, c) in chars { offset_map[idx] = new_idx; match c { diff --git a/crates/settings/src/settings_json.rs b/crates/settings/src/settings_json.rs index 8080ec8d5f..f112ec811d 100644 --- a/crates/settings/src/settings_json.rs +++ b/crates/settings/src/settings_json.rs @@ -209,7 +209,7 @@ fn replace_value_in_json_text( if ch == ',' { removal_end = existing_value_range.end + offset + 1; // Also consume whitespace after the comma - while let Some((_, next_ch)) = chars.next() { + for (_, next_ch) in chars.by_ref() { if next_ch.is_whitespace() { removal_end += next_ch.len_utf8(); } else { diff --git a/crates/tab_switcher/src/tab_switcher.rs b/crates/tab_switcher/src/tab_switcher.rs index 12af124ec7..655b8a2e8f 100644 --- a/crates/tab_switcher/src/tab_switcher.rs +++ b/crates/tab_switcher/src/tab_switcher.rs @@ -307,7 +307,7 @@ impl TabSwitcherDelegate { (Reverse(history.get(&item.item.item_id())), item.item_index) ) } - eprintln!(""); + eprintln!(); all_items .sort_by_key(|tab| (Reverse(history.get(&tab.item.item_id())), tab.item_index)); all_items diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 0c16e3fb9d..5b4d327140 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1397,8 +1397,8 @@ fn possible_open_target( let found_entry = worktree .update(cx, |worktree, _| { let worktree_root = worktree.abs_path(); - let mut traversal = worktree.traverse_from_path(true, true, false, "".as_ref()); - while let Some(entry) = traversal.next() { + let traversal = worktree.traverse_from_path(true, true, false, "".as_ref()); + for entry in traversal { if let Some(path_in_worktree) = worktree_paths_to_check .iter() .find(|path_to_check| entry.path.ends_with(&path_to_check.path)) diff --git a/crates/vim/src/command.rs b/crates/vim/src/command.rs index 79d18a85e9..b57c916db9 100644 --- a/crates/vim/src/command.rs +++ b/crates/vim/src/command.rs @@ -1492,7 +1492,7 @@ impl OnMatchingLines { let mut search = String::new(); let mut escaped = false; - while let Some(c) = chars.next() { + for c in chars.by_ref() { if escaped { escaped = false; // unescape escaped parens diff --git a/crates/vim/src/normal/increment.rs b/crates/vim/src/normal/increment.rs index 115aef1dab..1d2a4e9b61 100644 --- a/crates/vim/src/normal/increment.rs +++ b/crates/vim/src/normal/increment.rs @@ -274,9 +274,9 @@ fn find_boolean(snapshot: &MultiBufferSnapshot, start: Point) -> Option<(Range