diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 25713001f217..95f26818c098 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -9,6 +9,7 @@ #![feature(iter_partition_in_place)] #![feature(let_chains)] #![feature(never_type)] +#![feature(round_char_boundary)] #![feature(rustc_private)] #![feature(stmt_expr_attributes)] #![feature(unwrap_infallible)] diff --git a/clippy_lints/src/literal_string_with_formatting_args.rs b/clippy_lints/src/literal_string_with_formatting_args.rs index 378be37fbac5..49353a1b76be 100644 --- a/clippy_lints/src/literal_string_with_formatting_args.rs +++ b/clippy_lints/src/literal_string_with_formatting_args.rs @@ -108,7 +108,15 @@ impl LateLintPass<'_> for LiteralStringWithFormattingArg { if error.span.end >= current.len() { break; } - current = ¤t[error.span.end + 1..]; + // We find the closest char to where the error location ends. + let pos = current.floor_char_boundary(error.span.end); + // We get the next character. + current = if let Some((next_char_pos, _)) = current[pos..].char_indices().nth(1) { + // We make the parser start from this new location. + ¤t[pos + next_char_pos..] + } else { + break; + }; diff_len = fmt_str.len() - current.len(); parser = Parser::new(current, None, None, false, ParseMode::Format); } else if let Piece::NextArgument(arg) = piece { diff --git a/tests/ui/literal_string_with_formatting_arg.rs b/tests/ui/literal_string_with_formatting_arg.rs index 20bd243aa300..f257c66f59d3 100644 --- a/tests/ui/literal_string_with_formatting_arg.rs +++ b/tests/ui/literal_string_with_formatting_arg.rs @@ -30,4 +30,8 @@ fn main() { }"; // Unicode characters escape should not lint either. "\u{0052}".to_string(); + + // Regression test for . + let x: Option = Some(0); + x.expect("{…}"); }