Skip to content

Commit 5b40aa5

Browse files
committed
Tweak output for 'add line' suggestion
1 parent 4087dea commit 5b40aa5

File tree

166 files changed

+634
-294
lines changed

Some content is hidden

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

166 files changed

+634
-294
lines changed

compiler/rustc_errors/src/emitter.rs

+40-1
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,12 @@ impl EmitterWriter {
18321832
}
18331833
let show_code_change = if has_deletion && !is_multiline {
18341834
DisplaySuggestion::Diff
1835+
} else if let [part] = &parts[..]
1836+
&& part.snippet.ends_with('\n')
1837+
&& part.snippet.trim() == complete.trim()
1838+
{
1839+
// We are adding a line(s) of code before code that was already there.
1840+
DisplaySuggestion::Add
18351841
} else if (parts.len() != 1 || parts[0].snippet.trim() != complete.trim())
18361842
&& !is_multiline
18371843
{
@@ -1879,7 +1885,9 @@ impl EmitterWriter {
18791885
row_num += line_end - line_start;
18801886
}
18811887
let mut unhighlighted_lines = Vec::new();
1888+
let mut last_pos = 0;
18821889
for (line_pos, (line, highlight_parts)) in lines.by_ref().zip(highlights).enumerate() {
1890+
last_pos = line_pos;
18831891
debug!(%line_pos, %line, ?highlight_parts);
18841892

18851893
// Remember lines that are not highlighted to hide them if needed
@@ -1963,13 +1971,39 @@ impl EmitterWriter {
19631971
is_multiline,
19641972
)
19651973
}
1974+
if let DisplaySuggestion::Add = show_code_change {
1975+
// The suggestion adds an entire line of code, ending on a newline, so we'll also
1976+
// print the *following* line, to provide context of what we're advicing people to
1977+
// do. Otherwise you would only see contextless code that can be confused for
1978+
// already existing code, despite the colors and UI elements.
1979+
let file_lines = sm
1980+
.span_to_lines(span.primary_span().unwrap().shrink_to_hi())
1981+
.expect("span_to_lines failed when emitting suggestion");
1982+
let line_num = sm.lookup_char_pos(parts[0].span.lo()).line;
1983+
if let Some(line) = file_lines.file.get_line(line_num - 1) {
1984+
let line = normalize_whitespace(&line);
1985+
self.draw_code_line(
1986+
&mut buffer,
1987+
&mut row_num,
1988+
&[],
1989+
line_num + last_pos + 1,
1990+
&line,
1991+
DisplaySuggestion::None,
1992+
max_line_num_len,
1993+
&file_lines,
1994+
is_multiline,
1995+
)
1996+
}
1997+
}
19661998

19671999
// This offset and the ones below need to be signed to account for replacement code
19682000
// that is shorter than the original code.
19692001
let mut offsets: Vec<(usize, isize)> = Vec::new();
19702002
// Only show an underline in the suggestions if the suggestion is not the
19712003
// entirety of the code being shown and the displayed code is not multiline.
1972-
if let DisplaySuggestion::Diff | DisplaySuggestion::Underline = show_code_change {
2004+
if let DisplaySuggestion::Diff | DisplaySuggestion::Underline | DisplaySuggestion::Add =
2005+
show_code_change
2006+
{
19732007
draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1);
19742008
for part in parts {
19752009
let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display;
@@ -2247,6 +2281,10 @@ impl EmitterWriter {
22472281
}
22482282
}
22492283
buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
2284+
} else if let DisplaySuggestion::Add = show_code_change {
2285+
buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
2286+
buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition);
2287+
buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
22502288
} else {
22512289
buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
22522290
draw_col_separator(buffer, *row_num, max_line_num_len + 1);
@@ -2281,6 +2319,7 @@ enum DisplaySuggestion {
22812319
Underline,
22822320
Diff,
22832321
None,
2322+
Add,
22842323
}
22852324

22862325
impl FileWithAnnotatedLines {

src/tools/clippy/tests/ui/crashes/ice-6252.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ LL | _n: PhantomData,
66
|
77
help: consider importing one of these items
88
|
9-
LL | use core::marker::PhantomData;
9+
LL + use core::marker::PhantomData;
10+
LL | trait TypeVal<T> {
1011
|
11-
LL | use serde::__private::PhantomData;
12+
LL + use serde::__private::PhantomData;
13+
LL | trait TypeVal<T> {
1214
|
13-
LL | use std::marker::PhantomData;
15+
LL + use std::marker::PhantomData;
16+
LL | trait TypeVal<T> {
1417
|
1518

1619
error[E0412]: cannot find type `VAL` in this scope

src/tools/clippy/tests/ui/derivable_impls.stderr

+16-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ LL | | }
1414
= help: remove the manual implementation...
1515
help: ...and instead derive it
1616
|
17-
LL | #[derive(Default)]
17+
LL + #[derive(Default)]
18+
LL | struct FooDefault<'a> {
1819
|
1920

2021
error: this `impl` can be derived
@@ -30,7 +31,8 @@ LL | | }
3031
= help: remove the manual implementation...
3132
help: ...and instead derive it
3233
|
33-
LL | #[derive(Default)]
34+
LL + #[derive(Default)]
35+
LL | struct TupleDefault(bool, i32, u64);
3436
|
3537

3638
error: this `impl` can be derived
@@ -46,7 +48,8 @@ LL | | }
4648
= help: remove the manual implementation...
4749
help: ...and instead derive it
4850
|
49-
LL | #[derive(Default)]
51+
LL + #[derive(Default)]
52+
LL | struct StrDefault<'a>(&'a str);
5053
|
5154

5255
error: this `impl` can be derived
@@ -62,7 +65,8 @@ LL | | }
6265
= help: remove the manual implementation...
6366
help: ...and instead derive it
6467
|
65-
LL | #[derive(Default)]
68+
LL + #[derive(Default)]
69+
LL | struct Y(u32);
6670
|
6771

6872
error: this `impl` can be derived
@@ -78,7 +82,8 @@ LL | | }
7882
= help: remove the manual implementation...
7983
help: ...and instead derive it
8084
|
81-
LL | #[derive(Default)]
85+
LL + #[derive(Default)]
86+
LL | struct WithoutSelfCurly {
8287
|
8388

8489
error: this `impl` can be derived
@@ -94,7 +99,8 @@ LL | | }
9499
= help: remove the manual implementation...
95100
help: ...and instead derive it
96101
|
97-
LL | #[derive(Default)]
102+
LL + #[derive(Default)]
103+
LL | struct WithoutSelfParan(bool);
98104
|
99105

100106
error: this `impl` can be derived
@@ -110,7 +116,8 @@ LL | | }
110116
= help: remove the manual implementation...
111117
help: ...and instead derive it
112118
|
113-
LL | #[derive(Default)]
119+
LL + #[derive(Default)]
120+
LL | pub struct RepeatDefault1 {
114121
|
115122

116123
error: this `impl` can be derived
@@ -126,7 +133,8 @@ LL | | }
126133
= help: remove the manual implementation...
127134
help: ...and instead derive it...
128135
|
129-
LL | #[derive(Default)]
136+
LL + #[derive(Default)]
137+
LL | pub enum SimpleEnum {
130138
|
131139
help: ...and mark the default variant
132140
|

src/tools/clippy/tests/ui/new_without_default.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ LL + fn default() -> Self {
1414
LL + Self::new()
1515
LL + }
1616
LL + }
17+
LL | impl Foo {
1718
|
1819

1920
error: you should consider adding a `Default` implementation for `Bar`
@@ -31,6 +32,7 @@ LL + fn default() -> Self {
3132
LL + Self::new()
3233
LL + }
3334
LL + }
35+
LL | impl Bar {
3436
|
3537

3638
error: you should consider adding a `Default` implementation for `LtKo<'c>`
@@ -48,6 +50,7 @@ LL + fn default() -> Self {
4850
LL + Self::new()
4951
LL + }
5052
LL + }
53+
LL | impl<'c> LtKo<'c> {
5154
|
5255

5356
error: you should consider adding a `Default` implementation for `NewNotEqualToDerive`
@@ -65,6 +68,7 @@ LL + fn default() -> Self {
6568
LL + Self::new()
6669
LL + }
6770
LL + }
71+
LL | impl NewNotEqualToDerive {
6872
|
6973

7074
error: you should consider adding a `Default` implementation for `FooGenerics<T>`
@@ -82,6 +86,7 @@ LL + fn default() -> Self {
8286
LL + Self::new()
8387
LL + }
8488
LL + }
89+
LL | impl<T> FooGenerics<T> {
8590
|
8691

8792
error: you should consider adding a `Default` implementation for `BarGenerics<T>`
@@ -99,6 +104,7 @@ LL + fn default() -> Self {
99104
LL + Self::new()
100105
LL + }
101106
LL + }
107+
LL | impl<T: Copy> BarGenerics<T> {
102108
|
103109

104110
error: you should consider adding a `Default` implementation for `Foo<T>`

tests/ui/array-slice-vec/repeat_empty_ok.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ LL | let headers = [Header{value: &[]}; 128];
77
= note: the `Copy` trait is required because this value will be copied for each element of the array
88
help: consider annotating `Header<'_>` with `#[derive(Copy)]`
99
|
10-
LL | #[derive(Copy)]
10+
LL + #[derive(Copy)]
11+
LL | pub struct Header<'a> {
1112
|
1213

1314
error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
@@ -19,7 +20,8 @@ LL | let headers = [Header{value: &[0]}; 128];
1920
= note: the `Copy` trait is required because this value will be copied for each element of the array
2021
help: consider annotating `Header<'_>` with `#[derive(Copy)]`
2122
|
22-
LL | #[derive(Copy)]
23+
LL + #[derive(Copy)]
24+
LL | pub struct Header<'a> {
2325
|
2426

2527
error: aborting due to 2 previous errors

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ LL | type Ty: Clone = NotClone;
1111
| ^^^^^ required by this bound in `Tr::Ty`
1212
help: consider annotating `NotClone` with `#[derive(Clone)]`
1313
|
14-
LL | #[derive(Clone)]
14+
LL + #[derive(Clone)]
15+
LL | struct NotClone;
1516
|
1617

1718
error[E0277]: the trait bound `NotClone: Clone` is not satisfied
@@ -30,7 +31,8 @@ LL | type Ty = NotClone;
3031
| -- required by a bound in this associated type
3132
help: consider annotating `NotClone` with `#[derive(Clone)]`
3233
|
33-
LL | #[derive(Clone)]
34+
LL + #[derive(Clone)]
35+
LL | struct NotClone;
3436
|
3537

3638
error[E0277]: the trait bound `T: Clone` is not satisfied

tests/ui/binop/issue-28837.stderr

+12-6
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,8 @@ LL | struct A;
157157
| ^^^^^^^^ must implement `PartialEq<_>`
158158
help: consider annotating `A` with `#[derive(PartialEq)]`
159159
|
160-
LL | #[derive(PartialEq)]
160+
LL + #[derive(PartialEq)]
161+
LL | struct A;
161162
|
162163

163164
error[E0369]: binary operation `!=` cannot be applied to type `A`
@@ -175,7 +176,8 @@ LL | struct A;
175176
| ^^^^^^^^ must implement `PartialEq<_>`
176177
help: consider annotating `A` with `#[derive(PartialEq)]`
177178
|
178-
LL | #[derive(PartialEq)]
179+
LL + #[derive(PartialEq)]
180+
LL | struct A;
179181
|
180182

181183
error[E0369]: binary operation `<` cannot be applied to type `A`
@@ -193,7 +195,8 @@ LL | struct A;
193195
| ^^^^^^^^ must implement `PartialOrd<_>`
194196
help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
195197
|
196-
LL | #[derive(PartialEq, PartialOrd)]
198+
LL + #[derive(PartialEq, PartialOrd)]
199+
LL | struct A;
197200
|
198201

199202
error[E0369]: binary operation `<=` cannot be applied to type `A`
@@ -211,7 +214,8 @@ LL | struct A;
211214
| ^^^^^^^^ must implement `PartialOrd<_>`
212215
help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
213216
|
214-
LL | #[derive(PartialEq, PartialOrd)]
217+
LL + #[derive(PartialEq, PartialOrd)]
218+
LL | struct A;
215219
|
216220

217221
error[E0369]: binary operation `>` cannot be applied to type `A`
@@ -229,7 +233,8 @@ LL | struct A;
229233
| ^^^^^^^^ must implement `PartialOrd<_>`
230234
help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
231235
|
232-
LL | #[derive(PartialEq, PartialOrd)]
236+
LL + #[derive(PartialEq, PartialOrd)]
237+
LL | struct A;
233238
|
234239

235240
error[E0369]: binary operation `>=` cannot be applied to type `A`
@@ -247,7 +252,8 @@ LL | struct A;
247252
| ^^^^^^^^ must implement `PartialOrd<_>`
248253
help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
249254
|
250-
LL | #[derive(PartialEq, PartialOrd)]
255+
LL + #[derive(PartialEq, PartialOrd)]
256+
LL | struct A;
251257
|
252258

253259
error: aborting due to 15 previous errors

tests/ui/box/unit/unique-pinned-nocopy.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ LL | let _j = i.clone();
1919
candidate #1: `Clone`
2020
help: consider annotating `R` with `#[derive(Clone)]`
2121
|
22-
LL | #[derive(Clone)]
22+
LL + #[derive(Clone)]
23+
LL | struct R {
2324
|
2425

2526
error: aborting due to previous error

tests/ui/coherence/coherence_inherent.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ LL | s.the_fn();
77
= help: items from traits can only be used if the trait is in scope
88
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
99
|
10-
LL | use Lib::TheTrait;
10+
LL + use Lib::TheTrait;
11+
LL | use Lib::TheStruct;
1112
|
1213

1314
error: aborting due to previous error

tests/ui/coherence/coherence_inherent_cc.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ LL | s.the_fn();
77
= help: items from traits can only be used if the trait is in scope
88
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
99
|
10-
LL | use coherence_inherent_cc_lib::TheTrait;
10+
LL + use coherence_inherent_cc_lib::TheTrait;
11+
LL | use coherence_inherent_cc_lib::TheStruct;
1112
|
1213

1314
error: aborting due to previous error

tests/ui/const-generics/generic_const_exprs/issue-94287.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | If<{ FRAC <= 32 }>: True,
88
help: consider enabling this feature
99
--> $DIR/issue-94287.rs:1:1
1010
|
11+
LL + #![feature(generic_const_exprs)]
1112
LL | #![feature(generic_const_exprs)]
1213
|
1314

tests/ui/const-generics/issues/issue-82956.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ LL | let mut iter = IntoIter::new(self);
66
|
77
help: consider importing one of these items
88
|
9-
LL | use std::array::IntoIter;
9+
LL + use std::array::IntoIter;
10+
LL | pub struct ConstCheck<const CHECK: bool>;
1011
|
11-
LL | use std::collections::binary_heap::IntoIter;
12+
LL + use std::collections::binary_heap::IntoIter;
13+
LL | pub struct ConstCheck<const CHECK: bool>;
1214
|
13-
LL | use std::collections::btree_map::IntoIter;
15+
LL + use std::collections::btree_map::IntoIter;
16+
LL | pub struct ConstCheck<const CHECK: bool>;
1417
|
15-
LL | use std::collections::btree_set::IntoIter;
18+
LL + use std::collections::btree_set::IntoIter;
19+
LL | pub struct ConstCheck<const CHECK: bool>;
1620
|
1721
and 8 other candidates
1822

tests/ui/consts/const-blocks/fn-call-in-non-const.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ LL | let _: [Option<Bar>; 2] = [no_copy(); 2];
1010
= help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
1111
help: consider annotating `Bar` with `#[derive(Copy)]`
1212
|
13-
LL | #[derive(Copy)]
13+
LL + #[derive(Copy)]
14+
LL | struct Bar;
1415
|
1516

1617
error: aborting due to previous error

0 commit comments

Comments
 (0)