Skip to content

Commit d6579da

Browse files
More sophisticated span trimming
1 parent 28b83ee commit d6579da

File tree

108 files changed

+852
-1015
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+852
-1015
lines changed

compiler/rustc_errors/src/lib.rs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ use rustc_macros::{Decodable, Encodable};
7171
pub use rustc_span::ErrorGuaranteed;
7272
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
7373
use rustc_span::source_map::SourceMap;
74-
use rustc_span::{DUMMY_SP, Loc, Span};
74+
use rustc_span::{BytePos, DUMMY_SP, Loc, Span};
7575
pub use snippet::Style;
7676
// Used by external projects such as `rust-gpu`.
7777
// See https://github.com/rust-lang/rust/pull/115393.
@@ -237,10 +237,9 @@ impl SubstitutionPart {
237237
/// it with "abx" is, since the "c" character is lost.
238238
pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool {
239239
self.is_replacement(sm)
240-
&& !sm.span_to_snippet(self.span).is_ok_and(|snippet| {
241-
self.snippet.trim_start().starts_with(snippet.trim_start())
242-
|| self.snippet.trim_end().ends_with(snippet.trim_end())
243-
})
240+
&& !sm
241+
.span_to_snippet(self.span)
242+
.is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some())
244243
}
245244

246245
fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool {
@@ -257,16 +256,40 @@ impl SubstitutionPart {
257256
let Ok(snippet) = sm.span_to_snippet(self.span) else {
258257
return;
259258
};
260-
if self.snippet.starts_with(&snippet) {
261-
self.span = self.span.shrink_to_hi();
262-
self.snippet = self.snippet[snippet.len()..].to_string();
263-
} else if self.snippet.ends_with(&snippet) {
264-
self.span = self.span.shrink_to_lo();
265-
self.snippet = self.snippet[..self.snippet.len() - snippet.len()].to_string();
259+
260+
if let Some((prefix, substr, suffix)) = as_substr(&snippet, &self.snippet) {
261+
self.span = Span::new(
262+
self.span.lo() + BytePos(prefix as u32),
263+
self.span.hi() - BytePos(suffix as u32),
264+
self.span.ctxt(),
265+
self.span.parent(),
266+
);
267+
self.snippet = substr.to_string();
266268
}
267269
}
268270
}
269271

272+
/// Given an original string like `AACC`, and a suggestion like `AABBCC`, try to detect
273+
/// the case where a substring of the suggestion is "sandwiched" in the original, like
274+
/// `BB` is. Return the length of the prefix, the "trimmed" suggestion, and the length
275+
/// of the suffix.
276+
fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> {
277+
let common_prefix = original
278+
.chars()
279+
.zip(suggestion.chars())
280+
.take_while(|(c1, c2)| c1 == c2)
281+
.map(|(c, _)| c.len_utf8())
282+
.sum();
283+
let original = &original[common_prefix..];
284+
let suggestion = &suggestion[common_prefix..];
285+
if suggestion.ends_with(original) {
286+
let common_suffix = original.len();
287+
Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix))
288+
} else {
289+
None
290+
}
291+
}
292+
270293
impl CodeSuggestion {
271294
/// Returns the assembled code suggestions, whether they should be shown with an underline
272295
/// and whether the substitution only differs in capitalization.

tests/ui/argument-suggestions/basic.stderr

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ LL | fn missing(_i: u32) {}
4242
| ^^^^^^^ -------
4343
help: provide the argument
4444
|
45-
LL - missing();
46-
LL + missing(/* u32 */);
47-
|
45+
LL | missing(/* u32 */);
46+
| +++++++++
4847

4948
error[E0308]: arguments to this function are incorrect
5049
--> $DIR/basic.rs:23:5
@@ -98,9 +97,8 @@ LL | let closure = |x| x;
9897
| ^^^
9998
help: provide the argument
10099
|
101-
LL - closure();
102-
LL + closure(/* x */);
103-
|
100+
LL | closure(/* x */);
101+
| +++++++
104102

105103
error: aborting due to 6 previous errors
106104

tests/ui/argument-suggestions/display-is-suggestable.stderr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ LL | fn foo(x: &(dyn Display + Send)) {}
1111
| ^^^ ------------------------
1212
help: provide the argument
1313
|
14-
LL - foo();
15-
LL + foo(/* &dyn std::fmt::Display + Send */);
16-
|
14+
LL | foo(/* &dyn std::fmt::Display + Send */);
15+
| +++++++++++++++++++++++++++++++++++
1716

1817
error: aborting due to 1 previous error
1918

tests/ui/argument-suggestions/extern-fn-arg-names.stderr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ LL | fn dstfn(src: i32, dst: err);
1717
| ^^^^^ ---
1818
help: provide the argument
1919
|
20-
LL - dstfn(1);
21-
LL + dstfn(1, /* dst */);
22-
|
20+
LL | dstfn(1, /* dst */);
21+
| +++++++++++
2322

2423
error: aborting due to 2 previous errors
2524

tests/ui/argument-suggestions/issue-97197.stderr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ LL | pub fn g(a1: (), a2: bool, a3: bool, a4: bool, a5: bool, a6: ()) -> () {}
1111
| ^ -------- -------- -------- --------
1212
help: provide the arguments
1313
|
14-
LL - g((), ());
15-
LL + g((), /* bool */, /* bool */, /* bool */, /* bool */, ());
16-
|
14+
LL | g((), /* bool */, /* bool */, /* bool */, /* bool */, ());
15+
| +++++++++++++++++++++++++++++++++++++++++++++++
1716

1817
error: aborting due to 1 previous error
1918

tests/ui/argument-suggestions/issue-98894.stderr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ LL | (|_, ()| ())(if true {} else {return;});
1111
| ^^^^^^^
1212
help: provide the argument
1313
|
14-
LL - (|_, ()| ())(if true {} else {return;});
15-
LL + (|_, ()| ())(if true {} else {return;}, ());
16-
|
14+
LL | (|_, ()| ())(if true {} else {return;}, ());
15+
| ++++
1716

1817
error: aborting due to 1 previous error
1918

tests/ui/argument-suggestions/issue-98897.stderr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ LL | (|_, ()| ())([return, ()]);
1111
| ^^^^^^^
1212
help: provide the argument
1313
|
14-
LL - (|_, ()| ())([return, ()]);
15-
LL + (|_, ()| ())([return, ()], ());
16-
|
14+
LL | (|_, ()| ())([return, ()], ());
15+
| ++++
1716

1817
error: aborting due to 1 previous error
1918

tests/ui/argument-suggestions/issue-99482.stderr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ LL | let f = |_: (), f: fn()| f;
1111
| ^^^^^^^^^^^^^^^^
1212
help: provide the argument
1313
|
14-
LL - let _f = f(main);
15-
LL + let _f = f((), main);
16-
|
14+
LL | let _f = f((), main);
15+
| +++
1716

1817
error: aborting due to 1 previous error
1918

tests/ui/argument-suggestions/missing_arguments.stderr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ LL | fn one_arg(_a: i32) {}
1111
| ^^^^^^^ -------
1212
help: provide the argument
1313
|
14-
LL - one_arg();
15-
LL + one_arg(/* i32 */);
16-
|
14+
LL | one_arg(/* i32 */);
15+
| +++++++++
1716

1817
error[E0061]: this function takes 2 arguments but 0 arguments were supplied
1918
--> $DIR/missing_arguments.rs:14:3

tests/ui/associated-consts/associated-const-ambiguity-report.stderr

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ LL | const ID: i32 = 1;
1616
| ^^^^^^^^^^^^^
1717
help: use fully-qualified syntax to disambiguate
1818
|
19-
LL - const X: i32 = <i32>::ID;
20-
LL + const X: i32 = <i32 as Bar>::ID;
21-
|
22-
LL - const X: i32 = <i32>::ID;
23-
LL + const X: i32 = <i32 as Foo>::ID;
24-
|
19+
LL | const X: i32 = <i32 as Bar>::ID;
20+
| ++++++
21+
LL | const X: i32 = <i32 as Foo>::ID;
22+
| ++++++
2523

2624
error: aborting due to 1 previous error
2725

0 commit comments

Comments
 (0)