diff --git a/compiler-cli/src/add.rs b/compiler-cli/src/add.rs index ac666b796..19a0d1550 100644 --- a/compiler-cli/src/add.rs +++ b/compiler-cli/src/add.rs @@ -2,6 +2,7 @@ // SPDX-FileCopyrightText: 2021 The Gleam contributors use camino::{Utf8Path, Utf8PathBuf}; +use std::fmt::Write as _; use gleam_core::{ Error, Result, @@ -113,10 +114,12 @@ fn read_toml_edit(name: &Utf8Path) -> Result { fn version_to_string(version: &Version) -> String { let mut text = String::new(); - text.push_str(&format!( + let _ = write!( + text, "{}.{}.{}", version.major, version.minor, version.patch - )); + ); + if !version.pre.is_empty() { text.push('-'); for (i, identifier) in version.pre.iter().enumerate() { @@ -130,7 +133,7 @@ fn version_to_string(version: &Version) -> String { } } if let Some(build) = version.build.as_ref() { - text.push_str(&format!("+{build}")); + let _ = write!(text, "+{build}"); } text } diff --git a/compiler-cli/src/lib.rs b/compiler-cli/src/lib.rs index b6df93792..afe45d638 100644 --- a/compiler-cli/src/lib.rs +++ b/compiler-cli/src/lib.rs @@ -24,6 +24,7 @@ clippy::verbose_file_reads, clippy::unnested_or_patterns, clippy::default_trait_access, + clippy::format_push_string, rust_2018_idioms, missing_debug_implementations, missing_copy_implementations, diff --git a/compiler-core/src/derivation_tree.rs b/compiler-core/src/derivation_tree.rs index 0034c16b5..381e4eaba 100644 --- a/compiler-core/src/derivation_tree.rs +++ b/compiler-core/src/derivation_tree.rs @@ -13,6 +13,7 @@ use petgraph::prelude::StableGraph; use pubgrub::External; use pubgrub::{DerivationTree, Derived, Ranges}; use std::collections::HashMap; +use std::fmt::Write as _; use std::hash::RandomState; use std::ops::Bound::{Excluded, Included, Unbounded}; use std::sync::Arc; @@ -171,10 +172,11 @@ impl DerivationTreePrinter { .ranges_between(previous, next) .expect("path edge is in the graph"); - message.push_str(&format!( + let _ = write!( + message, "\n - {previous_name} requires {next_name} {}", pretty_range(next_range) - )); + ); previous = next; } message diff --git a/compiler-core/src/docs/tests.rs b/compiler-core/src/docs/tests.rs index 5c9bcf5cb..b2d8440a7 100644 --- a/compiler-core/src/docs/tests.rs +++ b/compiler-core/src/docs/tests.rs @@ -3,6 +3,7 @@ use std::{ collections::{HashMap, HashSet}, + fmt::Write as _, time::SystemTime, }; @@ -200,7 +201,7 @@ fn compile_documentation( output.push_str("---- SOURCE CODE\n"); for (_package, name, src) in modules { - output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); + let _ = write!(output, "-- {name}.gleam\n{src}\n\n"); } output.push_str("-- "); output.push_str(module_name); diff --git a/compiler-core/src/error.rs b/compiler-core/src/error.rs index c1229c916..75760af4b 100644 --- a/compiler-core/src/error.rs +++ b/compiler-core/src/error.rs @@ -7,6 +7,7 @@ use crate::bit_array::UnsupportedOption; use crate::build::{Origin, Outcome, Runtime, Target}; use crate::dependency::{PackageFetcher, ResolutionError}; use crate::diagnostic::{Diagnostic, ExtraLabel, Label, Location}; +use std::fmt::Write as _; use crate::derivation_tree::DerivationTreePrinter; use crate::parse::error::ParseErrorDetails; @@ -3535,7 +3536,7 @@ but no type in scope with that name." }; text.push_str(message); for module_name in possible_modules { - text.push_str(&format!(" - {module_name}.{name}\n")) + let _ = writeln!(text, " - {module_name}.{name}"); } } @@ -4648,10 +4649,11 @@ here takes {expected_string}.\n" the `use` callback function.\n", ) } else { - text.push_str(&format!( + let _ = writeln!( + text, "You supplied {supplied_arguments_string} \ -and the final one is the `use` callback function.\n" - )); +and the final one is the `use` callback function." + ); } } else { text.push_str( diff --git a/compiler-core/src/javascript/tests.rs b/compiler-core/src/javascript/tests.rs index b5c06bdc6..f1d5214d6 100644 --- a/compiler-core/src/javascript/tests.rs +++ b/compiler-core/src/javascript/tests.rs @@ -47,13 +47,14 @@ pub static CURRENT_PACKAGE: &str = "thepackage"; #[macro_export] macro_rules! assert_js { ($(($name:literal, $module_src:literal)),+, $src:literal $(,)?) => { + use std::fmt::Write as _; let compiled = $crate::javascript::tests::compile_js($src, vec![$(($crate::javascript::tests::CURRENT_PACKAGE, $name, $module_src)),*]); let mut output = String::from("----- SOURCE CODE\n"); for (name, src) in [$(($name, $module_src)),*] { - output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); + let _ = write!(output, "-- {name}.gleam\n{src}\n\n"); } - output.push_str(&format!("-- main.gleam\n{}\n\n----- COMPILED JAVASCRIPT\n{compiled}", $src)); + let _ = write!(output, "-- main.gleam\n{}\n\n----- COMPILED JAVASCRIPT\n{compiled}", $src); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; @@ -332,13 +333,11 @@ pub fn source_map_to_string(src: &str, compiled: &str, source_map: SourceMap) -> src_line_numbers.byte_index(Position::new(*next_src_line, *next_src_col)) as usize; let next_compiled_index = compiled_line_numbers.byte_index(Position::new(*next_dst_line, *next_dst_col)) as usize; - output.push_str(&format!("{}\n", &src[src_index..next_src_index])); - output.push_str("⏷\n"); - output.push_str(&format!( - "{}\n", - &compiled[compiled_index..next_compiled_index] - )); - output.push_str("----- \n"); + + output.push_str(&src[src_index..next_src_index]); + output.push_str("\n⏷\n"); + output.push_str(&compiled[compiled_index..next_compiled_index]); + output.push_str("\n----- \n"); prev_compiled_index = next_compiled_index; } // Print the last mapping. this needs to be done separately because the last mapping @@ -353,15 +352,17 @@ pub fn source_map_to_string(src: &str, compiled: &str, source_map: SourceMap) -> let next_src_index = src_line_numbers .byte_index(Position::new(next_src_token.0, next_src_token.1)) as usize; - output.push_str(&format!("{}\n", &src[src_index..next_src_index])); + output.push_str(&src[src_index..next_src_index]); + output.push('\n'); } None => { // If there is no next src token, print the rest of the source and compiled code - output.push_str(&format!("{}\n", &src[src_index..])); + output.push_str(&src[src_index..]); + output.push('\n'); } } output.push_str("⏷\n"); - output.push_str(&format!("{}\n", &compiled[prev_compiled_index..])); - output.push_str("----- \n"); + output.push_str(&compiled[prev_compiled_index..]); + output.push_str("\n----- \n"); output } diff --git a/compiler-core/src/lib.rs b/compiler-core/src/lib.rs index c1cd22c3c..50769b388 100644 --- a/compiler-core/src/lib.rs +++ b/compiler-core/src/lib.rs @@ -25,6 +25,7 @@ clippy::verbose_file_reads, clippy::unnested_or_patterns, clippy::default_trait_access, + clippy::format_push_string, rust_2018_idioms, missing_debug_implementations, missing_copy_implementations, diff --git a/compiler-core/src/type_/tests.rs b/compiler-core/src/type_/tests.rs index d21c685b7..13ad6ca70 100644 --- a/compiler-core/src/type_/tests.rs +++ b/compiler-core/src/type_/tests.rs @@ -90,6 +90,8 @@ macro_rules! assert_module_error { }; ($(($name:expr, $module_src:literal)),+, $src:literal $(,)?) => { + use std::fmt::Write as _; + let error = $crate::type_::tests::module_error( $src, vec![ @@ -99,13 +101,15 @@ macro_rules! assert_module_error { let mut output = String::from("----- SOURCE CODE\n"); for (name, src) in [$(($name, $module_src)),*] { - output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); + let _ = write!(output, "-- {name}.gleam\n{src}\n\n"); } - output.push_str(&format!("-- main.gleam\n{}\n\n----- ERROR\n{error}", $src)); + let _ = write!(output, "-- main.gleam\n{}\n\n----- ERROR\n{error}", $src); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; ($(($package:literal, $name:expr, $module_src:literal)),+, $src:literal $(,)?) => { + use std::fmt::Write as _; + let error = $crate::type_::tests::module_error( $src, vec![ @@ -115,9 +119,9 @@ macro_rules! assert_module_error { let mut output = String::from("----- SOURCE CODE\n"); for (name, src) in [$(($name, $module_src)),*] { - output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); + let _ = write!(output, "-- {name}.gleam\n{src}\n\n"); } - output.push_str(&format!("-- main.gleam\n{}\n\n----- ERROR\n{error}", $src)); + let _ = write!(output, "-- main.gleam\n{}\n\n----- ERROR\n{error}", $src); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; } @@ -231,6 +235,8 @@ macro_rules! assert_warning { }; ($(($name:expr, $module_src:literal)),+, $src:literal $(,)?) => { + use std::fmt::Write as _; + let warning = $crate::type_::tests::get_printed_warnings( $src, vec![ @@ -243,13 +249,15 @@ macro_rules! assert_warning { let mut output = String::from("----- SOURCE CODE\n"); for (name, src) in [$(($name, $module_src)),*] { - output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); + let _ = write!(output, "-- {name}.gleam\n{src}\n\n"); } - output.push_str(&format!("-- main.gleam\n{}\n\n----- WARNING\n{warning}", $src)); + let _ = write!(output, "-- main.gleam\n{}\n\n----- WARNING\n{warning}", $src); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; ($(($package:expr, $name:expr, $module_src:literal)),+, $src:expr) => { + use std::fmt::Write as _; + let warning = $crate::type_::tests::get_printed_warnings( $src, vec![$(($package, $name, $module_src)),*], @@ -260,9 +268,9 @@ macro_rules! assert_warning { let mut output = String::from("----- SOURCE CODE\n"); for (name, src) in [$(($name, $module_src)),*] { - output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); + let _ = write!(output, "-- {name}.gleam\n{src}\n\n"); } - output.push_str(&format!("-- main.gleam\n{}\n\n----- WARNING\n{warning}", $src)); + let _ = write!(output, "-- main.gleam\n{}\n\n----- WARNING\n{warning}", $src); insta::assert_snapshot!(insta::internals::AutoName, output, $src); }; } diff --git a/compiler-core/src/warning.rs b/compiler-core/src/warning.rs index a350f94d2..d01bbcdfe 100644 --- a/compiler-core/src/warning.rs +++ b/compiler-core/src/warning.rs @@ -22,6 +22,7 @@ use debug_ignore::DebugIgnore; use ecow::EcoString; use itertools::Itertools; use std::{ + fmt::Write as _, io::Write, sync::{Arc, atomic::Ordering}, }; @@ -1100,9 +1101,12 @@ Either change the pattern or use `panic` to unconditionally fail.", }; let mut text = format!("`{name}` is not a function"); match arguments { - 0 => text.push_str(&format!( - ", you can just write `{name}` instead of `{name}()`." - )), + 0 => { + let _ = write!( + text, + ", you can just write `{name}` instead of `{name}()`." + ); + } 1 => text.push_str( " and will crash before it can do anything with this argument.", ), diff --git a/language-server/src/lib.rs b/language-server/src/lib.rs index 065983fec..feba8ef71 100644 --- a/language-server/src/lib.rs +++ b/language-server/src/lib.rs @@ -23,6 +23,7 @@ clippy::verbose_file_reads, clippy::unnested_or_patterns, clippy::default_trait_access, + clippy::format_push_string, rust_2018_idioms, missing_debug_implementations, missing_copy_implementations, diff --git a/language-server/src/tests/action.rs b/language-server/src/tests/action.rs index 147dcf49e..4527122c4 100644 --- a/language-server/src/tests/action.rs +++ b/language-server/src/tests/action.rs @@ -6,6 +6,7 @@ use lsp_types::{ CodeActionContext, CodeActionParams, DocumentChange, PartialResultParams, Position, Uri as Url, WorkDoneProgressParams, }; +use std::fmt::Write as _; use super::*; use crate::path; @@ -248,7 +249,7 @@ macro_rules! assert_code_action { ); if !file_operations.is_empty() { - output.push_str(&format!("\n----- FILE OPERATIONS -----\n{file_operations}")); + let _ = write!(output, "\n----- FILE OPERATIONS -----\n{file_operations}"); } insta::assert_snapshot!(insta::internals::AutoName, output, src); diff --git a/language-server/src/tests/document_highlight.rs b/language-server/src/tests/document_highlight.rs index 47c0a571c..3d5590438 100644 --- a/language-server/src/tests/document_highlight.rs +++ b/language-server/src/tests/document_highlight.rs @@ -86,6 +86,8 @@ macro_rules! assert_highlights { }; ($project:expr, $position:expr $(,)?) => { + use std::fmt::Write as _; + let project = $project; let src = project.src; let position = $position.find_position(src); @@ -99,20 +101,22 @@ macro_rules! assert_highlights { } else { &Vec::new() }; - output.push_str(&format!( + let _ = write!( + output, "-- {name}.gleam\n{}\n\n", show_highlights(src, None, highlights_in_module) - )); + ); } let highlights_in_app_module = if module_name == "app" { &result } else { &Vec::new() }; - output.push_str(&format!( + let _ = write!( + output, "-- app.gleam\n{}", show_highlights(src, Some(position), highlights_in_app_module) - )); + ); insta::assert_snapshot!(insta::internals::AutoName, output, src); }; diff --git a/language-server/src/tests/reference.rs b/language-server/src/tests/reference.rs index 19d743f01..3cac0cfb7 100644 --- a/language-server/src/tests/reference.rs +++ b/language-server/src/tests/reference.rs @@ -94,6 +94,8 @@ macro_rules! assert_references { }; ($project:expr, $position:expr $(,)?) => { + use std::fmt::Write as _; + let project = $project; let src = project.src; let position = $position.find_position(src); @@ -101,19 +103,21 @@ macro_rules! assert_references { let mut output = String::new(); for (name, src) in project.root_package_modules.iter() { - output.push_str(&format!( + let _ = write!( + output, "-- {name}.gleam\n{}\n\n", show_references(src, None, result.get(*name).unwrap_or(&Vec::new())) - )); + ); } - output.push_str(&format!( + let _ = write!( + output, "-- app.gleam\n{}", show_references( src, Some(position), result.get("app").unwrap_or(&Vec::new()) ) - )); + ); insta::assert_snapshot!(insta::internals::AutoName, output, src); }; diff --git a/language-server/src/tests/rename.rs b/language-server/src/tests/rename.rs index 1689e64a2..853beaf29 100644 --- a/language-server/src/tests/rename.rs +++ b/language-server/src/tests/rename.rs @@ -2,6 +2,7 @@ // SPDX-FileCopyrightText: 2025 The Gleam contributors use std::collections::HashMap; +use std::fmt::Write as _; use lsp_types::{ Position, PrepareRenameParams, PrepareRenamePlaceholder, Range, RenameParams, @@ -119,7 +120,7 @@ fn display_result( ) -> String { let mut output = String::from("----- BEFORE RENAME\n"); for (name, src) in project.root_package_modules.iter() { - output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); + let _ = write!(output, "-- {name}.gleam\n{src}\n\n"); } let src = project.src; @@ -128,9 +129,10 @@ fn display_result( } else { src.to_string() }; - output.push_str(&format!( + let _ = write!( + output, "-- app.gleam\n{app_src_before}\n\n----- AFTER RENAME\n", - )); + ); for &(name, src) in project.root_package_modules.iter() { let used_name = if let Some(new_name) = renamed_modules.get(name) { @@ -138,21 +140,23 @@ fn display_result( } else { name }; - output.push_str(&format!( + let _ = write!( + output, "-- {used_name}.gleam\n{}\n\n", modules .get(name) .map(|string| string.as_str()) .unwrap_or(src) - )); + ); } - output.push_str(&format!( + let _ = write!( + output, "-- app.gleam\n{}", modules .get("app") .map(|string| string.as_str()) .unwrap_or(src) - )); + ); output } diff --git a/test-package-compiler/build.rs b/test-package-compiler/build.rs index f8b438ebf..633f50e46 100644 --- a/test-package-compiler/build.rs +++ b/test-package-compiler/build.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2022 The Gleam contributors +use std::fmt::Write as _; use std::path::PathBuf; pub fn main() { @@ -25,7 +26,8 @@ pub fn main() { for name in names { let path = cases.join(&name); let path = path.to_str().unwrap().replace('\\', "/"); - module.push_str(&format!( + let _ = write!( + module, r#" #[rustfmt::skip] #[test] @@ -38,7 +40,7 @@ fn {name}() {{ ); }} "# - )); + ); } let out = PathBuf::from("./src/generated_tests.rs");