Skip to content

Commit 469191f

Browse files
Trim suggestion parts to the subset that is purely additive
1 parent 0a66e8f commit 469191f

File tree

143 files changed

+299
-271
lines changed

Some content is hidden

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

143 files changed

+299
-271
lines changed

compiler/rustc_errors/src/emitter.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -1976,9 +1976,11 @@ impl HumanEmitter {
19761976
Some(Style::HeaderMsg),
19771977
);
19781978

1979+
let other_suggestions = suggestions.len().saturating_sub(MAX_SUGGESTIONS);
1980+
19791981
let mut row_num = 2;
19801982
for (i, (complete, parts, highlights, _)) in
1981-
suggestions.iter().enumerate().take(MAX_SUGGESTIONS)
1983+
suggestions.into_iter().enumerate().take(MAX_SUGGESTIONS)
19821984
{
19831985
debug!(?complete, ?parts, ?highlights);
19841986

@@ -2168,7 +2170,7 @@ impl HumanEmitter {
21682170
self.draw_code_line(
21692171
&mut buffer,
21702172
&mut row_num,
2171-
highlight_parts,
2173+
&highlight_parts,
21722174
line_pos + line_start,
21732175
line,
21742176
show_code_change,
@@ -2214,7 +2216,12 @@ impl HumanEmitter {
22142216
if let DisplaySuggestion::Diff | DisplaySuggestion::Underline | DisplaySuggestion::Add =
22152217
show_code_change
22162218
{
2217-
for part in parts {
2219+
for mut part in parts {
2220+
// If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the
2221+
// suggestion and snippet to look as if we just suggested to add
2222+
// `"b"`, which is typically much easier for the user to understand.
2223+
part.trim_trivial_replacements(sm);
2224+
22182225
let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) {
22192226
snippet
22202227
} else {
@@ -2377,9 +2384,12 @@ impl HumanEmitter {
23772384
row_num = row + 1;
23782385
}
23792386
}
2380-
if suggestions.len() > MAX_SUGGESTIONS {
2381-
let others = suggestions.len() - MAX_SUGGESTIONS;
2382-
let msg = format!("and {} other candidate{}", others, pluralize!(others));
2387+
if other_suggestions > 0 {
2388+
let msg = format!(
2389+
"and {} other candidate{}",
2390+
other_suggestions,
2391+
pluralize!(other_suggestions)
2392+
);
23832393
buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
23842394
}
23852395

compiler/rustc_errors/src/lib.rs

+18
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,24 @@ impl SubstitutionPart {
246246
sm.span_to_snippet(self.span)
247247
.map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty())
248248
}
249+
250+
/// Try to turn a replacement into an addition when the span that is being
251+
/// overwritten matches either the prefix or suffix of the replacement.
252+
fn trim_trivial_replacements(&mut self, sm: &SourceMap) {
253+
if self.snippet.is_empty() {
254+
return;
255+
}
256+
let Ok(snippet) = sm.span_to_snippet(self.span) else {
257+
return;
258+
};
259+
if self.snippet.starts_with(&snippet) {
260+
self.span = self.span.shrink_to_hi();
261+
self.snippet = self.snippet[snippet.len()..].to_string();
262+
} else if self.snippet.ends_with(&snippet) {
263+
self.span = self.span.shrink_to_lo();
264+
self.snippet = self.snippet[..self.snippet.len() - snippet.len()].to_string();
265+
}
266+
}
249267
}
250268

251269
impl CodeSuggestion {

tests/ui/associated-types/defaults-suitability.current.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ LL | type Baz = T;
135135
help: consider further restricting type parameter `T` with trait `Clone`
136136
|
137137
LL | Self::Baz: Clone, T: std::clone::Clone
138-
| ~~~~~~~~~~~~~~~~~~~~~~
138+
| ++++++++++++++++++++
139139

140140
error: aborting due to 8 previous errors
141141

tests/ui/associated-types/defaults-suitability.next.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ LL | type Baz = T;
135135
help: consider further restricting type parameter `T` with trait `Clone`
136136
|
137137
LL | Self::Baz: Clone, T: std::clone::Clone
138-
| ~~~~~~~~~~~~~~~~~~~~~~
138+
| ++++++++++++++++++++
139139

140140
error: aborting due to 8 previous errors
141141

tests/ui/associated-types/issue-38821.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ LL | impl<T: NotNull> IntoNullable for T {
1414
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
1515
|
1616
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull
17-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17+
| +++++++++++++++++++++++++++++++++++++
1818

1919
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
2020
--> $DIR/issue-38821.rs:40:1
@@ -38,7 +38,7 @@ LL | impl<T: NotNull> IntoNullable for T {
3838
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
3939
|
4040
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull
41-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41+
| +++++++++++++++++++++++++++++++++++++
4242

4343
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
4444
--> $DIR/issue-38821.rs:23:10

tests/ui/associated-types/issue-54108.current.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | type Size: Add<Output = Self::Size>;
1313
help: consider further restricting the associated type
1414
|
1515
LL | T: SubEncoder, <T as SubEncoder>::ActualSize: Add
16-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16+
| ++++++++++++++++++++++++++++++++++
1717

1818
error: aborting due to 1 previous error
1919

tests/ui/associated-types/issue-54108.next.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | type Size: Add<Output = Self::Size>;
1313
help: consider further restricting the associated type
1414
|
1515
LL | T: SubEncoder, <T as SubEncoder>::ActualSize: Add
16-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16+
| ++++++++++++++++++++++++++++++++++
1717

1818
error: aborting due to 1 previous error
1919

tests/ui/attributes/rustc_confusables.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ LL | x.inser();
3636
help: there is a method `insert` with a similar name
3737
|
3838
LL | x.insert();
39-
| ~~~~~~
39+
| +
4040

4141
error[E0599]: no method named `foo` found for struct `rustc_confusables_across_crate::BTreeSet` in the current scope
4242
--> $DIR/rustc_confusables.rs:15:7

tests/ui/attributes/rustc_confusables_std_cases.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ LL | let mut x = VecDeque::new();
3939
help: you might have meant to use `push_back`
4040
|
4141
LL | x.push_back(1);
42-
| ~~~~~~~~~
42+
| +++++
4343

4444
error[E0599]: no method named `length` found for struct `Vec<{integer}>` in the current scope
4545
--> $DIR/rustc_confusables_std_cases.rs:15:7
@@ -98,7 +98,7 @@ note: method defined here
9898
help: you might have meant to use `push_str`
9999
|
100100
LL | String::new().push_str("");
101-
| ~~~~~~~~
101+
| ++++
102102

103103
error[E0599]: no method named `append` found for struct `String` in the current scope
104104
--> $DIR/rustc_confusables_std_cases.rs:24:19

tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | self.layers.iter().fold(0, |result, mut layer| result + layer.proce
99
help: you may want to use `iter_mut` here
1010
|
1111
LL | self.layers.iter_mut().fold(0, |result, mut layer| result + layer.process())
12-
| ~~~~~~~~
12+
| ++++
1313

1414
error: aborting due to 1 previous error
1515

tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | vec.iter().flat_map(|container| container.things()).cloned().co
99
help: you may want to use `iter_mut` here
1010
|
1111
LL | vec.iter_mut().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>();
12-
| ~~~~~~~~
12+
| ++++
1313

1414
error: aborting due to 1 previous error
1515

tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | v.iter().for_each(|a| a.double());
99
help: you may want to use `iter_mut` here
1010
|
1111
LL | v.iter_mut().for_each(|a| a.double());
12-
| ~~~~~~~~
12+
| ++++
1313

1414
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
1515
--> $DIR/issue-62387-suggest-iter-mut.rs:25:39
@@ -22,7 +22,7 @@ LL | v.iter().rev().rev().for_each(|a| a.double());
2222
help: you may want to use `iter_mut` here
2323
|
2424
LL | v.iter_mut().rev().rev().for_each(|a| a.double());
25-
| ~~~~~~~~
25+
| ++++
2626

2727
error: aborting due to 2 previous errors
2828

tests/ui/c-variadic/issue-86053-1.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize
6464
help: a trait with a similar name exists
6565
|
6666
LL | self , ... , self , self , ... ) where Fn : FnOnce ( & 'a & 'b usize ) {
67-
| ~~
67+
| +
6868
help: you might be missing a type parameter
6969
|
7070
LL | fn ordering4 < 'a , 'b, F > ( a : , self , self , self ,

tests/ui/cfg/cfg-method-receiver.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ LL | cbor_map! { #[cfg(test)] 4};
1717
help: you must specify a concrete type for this numeric value, like `i32`
1818
|
1919
LL | cbor_map! { #[cfg(test)] 4_i32};
20-
| ~~~~~
20+
| ++++
2121

2222
error: aborting due to 2 previous errors
2323

tests/ui/check-cfg/diagnotics.cargo.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | #[cfg(featur = "foo")]
1818
help: there is a config with a similar name and value
1919
|
2020
LL | #[cfg(feature = "foo")]
21-
| ~~~~~~~
21+
| +
2222

2323
warning: unexpected `cfg` condition name: `featur`
2424
--> $DIR/diagnotics.rs:17:7

tests/ui/check-cfg/diagnotics.rustc.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LL | #[cfg(featur = "foo")]
2020
help: there is a config with a similar name and value
2121
|
2222
LL | #[cfg(feature = "foo")]
23-
| ~~~~~~~
23+
| +
2424

2525
warning: unexpected `cfg` condition name: `featur`
2626
--> $DIR/diagnotics.rs:17:7

tests/ui/closures/2229_closure_analysis/bad-pattern.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ LL | let PAT = v1;
109109
help: introduce a variable instead
110110
|
111111
LL | let PAT_var = v1;
112-
| ~~~~~~~
112+
| ++++
113113

114114
error: aborting due to 7 previous errors
115115

tests/ui/closures/2229_closure_analysis/issue-118144.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | V(x) = func_arg;
99
help: consider dereferencing to access the inner value using the Deref trait
1010
|
1111
LL | V(x) = &*func_arg;
12-
| ~~~~~~~~~~
12+
| ++
1313

1414
error: aborting due to 1 previous error
1515

tests/ui/closures/issue-78720.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ LL | _func: F,
1616
help: a trait with a similar name exists
1717
|
1818
LL | _func: Fn,
19-
| ~~
19+
| +
2020
help: you might be missing a type parameter
2121
|
2222
LL | struct Map2<Segment2, F> {

tests/ui/compare-method/bad-self-type.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> {
99
help: change the self-receiver type to match the trait
1010
|
1111
LL | fn poll(self: Pin<&mut MyFuture>, _: &mut Context<'_>) -> Poll<()> {
12-
| ~~~~~~~~~~~~~~~~~~~~~~~~
12+
| ++++++++++++++++++++
1313

1414
error[E0053]: method `foo` has an incompatible type for trait
1515
--> $DIR/bad-self-type.rs:22:18

tests/ui/const-generics/ensure_is_evaluatable.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LL | [(); N + 1]:,
1515
help: try adding a `where` bound
1616
|
1717
LL | [(); M + 1]:, [(); N + 1]:
18-
| ~~~~~~~~~~~~~~
18+
| ++++++++++++
1919

2020
error: aborting due to 1 previous error
2121

tests/ui/const-generics/fn_with_two_const_inputs.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LL | [(); N + 1]:,
1515
help: try adding a `where` bound
1616
|
1717
LL | [(); both(N + 1, M + 1)]:, [(); N + 1]:
18-
| ~~~~~~~~~~~~~~
18+
| ++++++++++++
1919

2020
error: aborting due to 1 previous error
2121

tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ LL | fn assert_impl<T: Trait>() {}
1717
help: try adding a `where` bound
1818
|
1919
LL | EvaluatableU128<{N as u128}>:, [(); { O as u128 } as usize]: {
20-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20+
| +++++++++++++++++++++++++++++
2121

2222
error[E0308]: mismatched types
2323
--> $DIR/abstract-const-as-cast-3.rs:17:5
@@ -52,7 +52,7 @@ LL | fn assert_impl<T: Trait>() {}
5252
help: try adding a `where` bound
5353
|
5454
LL | EvaluatableU128<{N as u128}>:, [(); { O as u128 } as usize]: {
55-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55+
| +++++++++++++++++++++++++++++
5656

5757
error[E0308]: mismatched types
5858
--> $DIR/abstract-const-as-cast-3.rs:20:5
@@ -115,7 +115,7 @@ LL | fn assert_impl<T: Trait>() {}
115115
help: try adding a `where` bound
116116
|
117117
LL | EvaluatableU128<{N as _}>:, [(); { O as u128 } as usize]: {
118-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118+
| +++++++++++++++++++++++++++++
119119

120120
error[E0308]: mismatched types
121121
--> $DIR/abstract-const-as-cast-3.rs:35:5
@@ -150,7 +150,7 @@ LL | fn assert_impl<T: Trait>() {}
150150
help: try adding a `where` bound
151151
|
152152
LL | EvaluatableU128<{N as _}>:, [(); { O as u128 } as usize]: {
153-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
153+
| +++++++++++++++++++++++++++++
154154

155155
error[E0308]: mismatched types
156156
--> $DIR/abstract-const-as-cast-3.rs:38:5

tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | bar::<{ T::ASSOC }>();
77
help: try adding a `where` bound
88
|
99
LL | fn foo<T: Trait, U: Trait>() where [(); U::ASSOC]:, [(); { T::ASSOC }]: {
10-
| ~~~~~~~~~~~~~~~~~~~~~
10+
| +++++++++++++++++++
1111

1212
error: aborting due to 1 previous error
1313

tests/ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ LL | foo::<_, L>([(); L + 1 + L]);
2727
help: try adding a `where` bound
2828
|
2929
LL | [(); (L - 1) + 1 + L]:, [(); L + 1 + L]:
30-
| ~~~~~~~~~~~~~~~~~~
30+
| ++++++++++++++++
3131

3232
error: unconstrained generic constant
3333
--> $DIR/issue_114151.rs:17:17

tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ LL | foo::<_, L>([(); L + 1 + L]);
1616
help: try adding a `where` bound
1717
|
1818
LL | [(); (L - 1) + 1 + L]:, [(); L + 1 + L]:
19-
| ~~~~~~~~~~~~~~~~~~
19+
| ++++++++++++++++
2020

2121
error: aborting due to 2 previous errors
2222

tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | let f: F = async { 1 };
1010
help: a trait with a similar name exists
1111
|
1212
LL | let f: Fn = async { 1 };
13-
| ~~
13+
| +
1414
help: you might be missing a type parameter
1515
|
1616
LL | fn f<T, F>(

tests/ui/consts/const-pattern-irrefutable.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | let a = 4;
1313
help: introduce a variable instead
1414
|
1515
LL | let a_var = 4;
16-
| ~~~~~
16+
| ++++
1717

1818
error[E0005]: refutable pattern in local binding
1919
--> $DIR/const-pattern-irrefutable.rs:28:9
@@ -48,7 +48,7 @@ LL | let d = (4, 4);
4848
help: introduce a variable instead
4949
|
5050
LL | let d_var = (4, 4);
51-
| ~~~~~
51+
| ++++
5252

5353
error[E0005]: refutable pattern in local binding
5454
--> $DIR/const-pattern-irrefutable.rs:36:9
@@ -70,7 +70,7 @@ LL | struct S {
7070
help: introduce a variable instead
7171
|
7272
LL | let e_var = S {
73-
| ~~~~~
73+
| ++++
7474

7575
error: aborting due to 4 previous errors
7676

tests/ui/did_you_mean/dont-suggest-hygienic-fields.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | const CRATE: Crate = Crate { fiel: () };
1111
help: a field with a similar name exists
1212
|
1313
LL | const CRATE: Crate = Crate { field: () };
14-
| ~~~~~
14+
| +
1515

1616
error[E0609]: no field `field` on type `Compound`
1717
--> $DIR/dont-suggest-hygienic-fields.rs:24:16

0 commit comments

Comments
 (0)