Skip to content

Commit 6e1a961

Browse files
committed
Update substring match for substitutions
1 parent 27050c0 commit 6e1a961

File tree

1 file changed

+26
-10
lines changed
  • compiler/rustc_errors/src

1 file changed

+26
-10
lines changed

compiler/rustc_errors/src/lib.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,20 +306,36 @@ impl TrimmedSubstitutionPart {
306306
/// `BB` is. Return the length of the prefix, the "trimmed" suggestion, and the length
307307
/// of the suffix.
308308
fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> {
309-
let common_prefix = original
309+
// Find common suffix by iterating backward through characters.
310+
// We search from the end first to prefer complete suffix matches,
311+
// which fixes prefix finding in cases like "sync" -> "std::sync"
312+
// where we want to recognize "sync" as the full suffix.
313+
let suffix: usize = original
310314
.chars()
311-
.zip(suggestion.chars())
315+
.rev()
316+
.zip(suggestion.chars().rev())
312317
.take_while(|(c1, c2)| c1 == c2)
313318
.map(|(c, _)| c.len_utf8())
314319
.sum();
315-
let original = &original[common_prefix..];
316-
let suggestion = &suggestion[common_prefix..];
317-
if suggestion.ends_with(original) {
318-
let common_suffix = original.len();
319-
Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix))
320-
} else {
321-
None
320+
321+
// After removing the common suffix, find any common prefix
322+
let prefix: usize = original[..original.len() - suffix]
323+
.chars()
324+
.zip(suggestion[..suggestion.len() - suffix].chars())
325+
.take_while(|(c1, c2)| c1 == c2)
326+
.map(|(c, _)| c.len_utf8())
327+
.sum();
328+
329+
// Check that the original is fully covered by prefix + suffix (nothing in the middle)
330+
if prefix + suffix != original.len() {
331+
return None;
322332
}
333+
334+
// Extract and return the sandwiched part from the suggestion
335+
let sandwiched = &suggestion[prefix..suggestion.len() - suffix];
336+
337+
// Only succeed if suggestion is actually different from original
338+
(sandwiched.len() > 0 || original.is_empty()).then_some((prefix, sandwiched, suffix))
323339
}
324340

325341
impl CodeSuggestion {
@@ -425,7 +441,7 @@ impl CodeSuggestion {
425441
return None;
426442
}
427443

428-
let mut highlights = vec![];
444+
let mut highlights: Vec<Vec<SubstitutionHighlight>> = vec![];
429445
// To build up the result, we do this for each span:
430446
// - push the line segment trailing the previous span
431447
// (at the beginning a "phantom" span pointing at the start of the line)

0 commit comments

Comments
 (0)