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

+34-11
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

+4-6
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

+2-3
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

+2-3
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

+2-3
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

+2-3
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

+2-3
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

+2-3
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

+2-3
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

+4-6
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

tests/ui/associated-inherent-types/issue-109768.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ LL | struct Wrapper<T>(T);
4343
| ^^^^^^^
4444
help: provide the argument
4545
|
46-
LL - const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3> = Wrapper();
47-
LL + const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3> = Wrapper(/* value */);
48-
|
46+
LL | const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3> = Wrapper(/* value */);
47+
| +++++++++++
4948

5049
error: aborting due to 4 previous errors
5150

tests/ui/associated-item/associated-item-enum.stderr

+6-9
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ LL | Enum::mispellable();
99
|
1010
help: there is an associated function `misspellable` with a similar name
1111
|
12-
LL - Enum::mispellable();
13-
LL + Enum::misspellable();
14-
|
12+
LL | Enum::misspellable();
13+
| +
1514

1615
error[E0599]: no variant or associated item named `mispellable_trait` found for enum `Enum` in the current scope
1716
--> $DIR/associated-item-enum.rs:18:11
@@ -24,9 +23,8 @@ LL | Enum::mispellable_trait();
2423
|
2524
help: there is an associated function `misspellable_trait` with a similar name
2625
|
27-
LL - Enum::mispellable_trait();
28-
LL + Enum::misspellable_trait();
29-
|
26+
LL | Enum::misspellable_trait();
27+
| +
3028

3129
error[E0599]: no variant or associated item named `MISPELLABLE` found for enum `Enum` in the current scope
3230
--> $DIR/associated-item-enum.rs:19:11
@@ -39,9 +37,8 @@ LL | Enum::MISPELLABLE;
3937
|
4038
help: there is an associated constant `MISSPELLABLE` with a similar name
4139
|
42-
LL - Enum::MISPELLABLE;
43-
LL + Enum::MISSPELLABLE;
44-
|
40+
LL | Enum::MISSPELLABLE;
41+
| +
4542

4643
error: aborting due to 3 previous errors
4744

tests/ui/binop/placement-syntax.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ LL | if x<-1 {
66
|
77
help: if you meant to write a comparison against a negative value, add a space in between `<` and `-`
88
|
9-
LL - if x<-1 {
10-
LL + if x< -1 {
11-
|
9+
LL | if x< -1 {
10+
| +
1211

1312
error: aborting due to 1 previous error
1413

tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,8 @@ LL | let _s2 = T { ..s0 };
116116
|
117117
help: clone the value from the field instead of using the functional record update syntax
118118
|
119-
LL - let _s2 = T { ..s0 };
120-
LL + let _s2 = T { b: s0.b.clone(), ..s0 };
121-
|
119+
LL | let _s2 = T { b: s0.b.clone(), ..s0 };
120+
| ++++++++++++++++
122121

123122
error[E0509]: cannot move out of type `T`, which implements the `Drop` trait
124123
--> $DIR/borrowck-struct-update-with-dtor.rs:47:32

tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ LL | let sfoo: *mut Foo = &mut SFOO;
99
= note: `#[warn(static_mut_refs)]` on by default
1010
help: use `&raw mut` instead to create a raw pointer
1111
|
12-
LL - let sfoo: *mut Foo = &mut SFOO;
13-
LL + let sfoo: *mut Foo = &raw mut SFOO;
14-
|
12+
LL | let sfoo: *mut Foo = &raw mut SFOO;
13+
| +++
1514

1615
warning: 1 warning emitted
1716

tests/ui/borrowck/issue-85765-closure.stderr

+6-9
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ LL | rofl.push(Vec::new());
66
|
77
help: consider changing this binding's type
88
|
9-
LL - let rofl: &Vec<Vec<i32>> = &mut test;
10-
LL + let rofl: &mut Vec<Vec<i32>> = &mut test;
11-
|
9+
LL | let rofl: &mut Vec<Vec<i32>> = &mut test;
10+
| +++
1211

1312
error[E0594]: cannot assign to `*r`, which is behind a `&` reference
1413
--> $DIR/issue-85765-closure.rs:13:9
@@ -29,9 +28,8 @@ LL | *x = 1;
2928
|
3029
help: consider changing this binding's type
3130
|
32-
LL - let x: &usize = &mut{0};
33-
LL + let x: &mut usize = &mut{0};
34-
|
31+
LL | let x: &mut usize = &mut{0};
32+
| +++
3533

3634
error[E0594]: cannot assign to `*y`, which is behind a `&` reference
3735
--> $DIR/issue-85765-closure.rs:27:9
@@ -41,9 +39,8 @@ LL | *y = 1;
4139
|
4240
help: consider changing this binding's type
4341
|
44-
LL - let y: &usize = &mut(0);
45-
LL + let y: &mut usize = &mut(0);
46-
|
42+
LL | let y: &mut usize = &mut(0);
43+
| +++
4744

4845
error: aborting due to 4 previous errors
4946

tests/ui/borrowck/issue-85765.stderr

+6-9
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ LL | rofl.push(Vec::new());
66
|
77
help: consider changing this binding's type
88
|
9-
LL - let rofl: &Vec<Vec<i32>> = &mut test;
10-
LL + let rofl: &mut Vec<Vec<i32>> = &mut test;
11-
|
9+
LL | let rofl: &mut Vec<Vec<i32>> = &mut test;
10+
| +++
1211

1312
error[E0594]: cannot assign to `*r`, which is behind a `&` reference
1413
--> $DIR/issue-85765.rs:12:5
@@ -29,9 +28,8 @@ LL | *x = 1;
2928
|
3029
help: consider changing this binding's type
3130
|
32-
LL - let x: &usize = &mut{0};
33-
LL + let x: &mut usize = &mut{0};
34-
|
31+
LL | let x: &mut usize = &mut{0};
32+
| +++
3533

3634
error[E0594]: cannot assign to `*y`, which is behind a `&` reference
3735
--> $DIR/issue-85765.rs:26:5
@@ -41,9 +39,8 @@ LL | *y = 1;
4139
|
4240
help: consider changing this binding's type
4341
|
44-
LL - let y: &usize = &mut(0);
45-
LL + let y: &mut usize = &mut(0);
46-
|
42+
LL | let y: &mut usize = &mut(0);
43+
| +++
4744

4845
error: aborting due to 4 previous errors
4946

tests/ui/c-variadic/variadic-ffi-1.stderr

+4-6
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ LL | fn foo(f: isize, x: u8, ...);
1717
| ^^^ - -
1818
help: provide the arguments
1919
|
20-
LL - foo();
21-
LL + foo(/* isize */, /* u8 */);
22-
|
20+
LL | foo(/* isize */, /* u8 */);
21+
| +++++++++++++++++++++
2322

2423
error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
2524
--> $DIR/variadic-ffi-1.rs:23:9
@@ -34,9 +33,8 @@ LL | fn foo(f: isize, x: u8, ...);
3433
| ^^^ -
3534
help: provide the argument
3635
|
37-
LL - foo(1);
38-
LL + foo(1, /* u8 */);
39-
|
36+
LL | foo(1, /* u8 */);
37+
| ++++++++++
4038

4139
error[E0308]: mismatched types
4240
--> $DIR/variadic-ffi-1.rs:25:56

tests/ui/cast/ice-cast-type-with-error-124848.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@ LL | struct MyType<'a>(Cell<Option<&'unpinned mut MyType<'a>>>, Pin);
4848
| ^^^^^^
4949
help: provide the argument
5050
|
51-
LL - let mut unpinned = MyType(Cell::new(None));
52-
LL + let mut unpinned = MyType(Cell::new(None), /* value */);
53-
|
51+
LL | let mut unpinned = MyType(Cell::new(None), /* value */);
52+
| +++++++++++++
5453

5554
error[E0606]: casting `&MyType<'_>` as `*const Cell<Option<&mut MyType<'_>>>` is invalid
5655
--> $DIR/ice-cast-type-with-error-124848.rs:14:20

tests/ui/conditional-compilation/cfg-attr-parse.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ LL | #[cfg_attr()]
77
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
88
help: missing condition and attribute
99
|
10-
LL - #[cfg_attr()]
11-
LL + #[cfg_attr(condition, attribute, other_attribute, ...)]
12-
|
10+
LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
11+
| ++++++++++++++++++++++++++++++++++++++++++
1312

1413
error: expected `,`, found end of `cfg_attr` input
1514
--> $DIR/cfg-attr-parse.rs:8:17

0 commit comments

Comments
 (0)