diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs b/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs index 757d8a3194..d9385bf6a9 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs +++ b/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs @@ -66,10 +66,11 @@ fn logging_f_string( // If the literal text contains a '%' placeholder, bail out: mixing // f-string interpolation with '%' placeholders is ambiguous for our // automatic conversion, so don't offer a fix for this case. - if lit.value.as_ref().contains('%') { + if lit.value.contains('%') { return; } - format_string.push_str(&lit.value.replace('\n', "\\n")); + + push_escaped_newlines(&lit.value, &mut format_string); } InterpolatedStringElement::Interpolation(interpolated) => { if interpolated.format_spec.is_some() @@ -117,6 +118,19 @@ fn logging_f_string( diagnostic.set_fix(fix); } +/// Push str replacing `\n` with `\\n` while writing directly into the +/// destination buffer, avoiding intermediate allocations. +#[inline] +fn push_escaped_newlines(literal: &str, destination: &mut String) { + for ch in literal.chars() { + if ch == '\n' { + destination.push_str("\\n"); + } else { + destination.push(ch); + } + } +} + /// Returns `true` if the attribute is a reserved attribute on the `logging` module's `LogRecord` /// class. fn is_reserved_attr(attr: &str) -> bool {