Skip to content

Commit d37e2f7

Browse files
committed
Auto merge of rust-lang#109786 - estebank:tweak-add-line-sugg, r=compiler-errors
Tweak output for 'add line' suggestion Closes rust-lang#108174
2 parents a29dada + 9fadcc1 commit d37e2f7

File tree

165 files changed

+458
-296
lines changed

Some content is hidden

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

165 files changed

+458
-296
lines changed

compiler/rustc_errors/src/emitter.rs

+49-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,14 +1885,23 @@ impl EmitterWriter {
18791885
row_num += line_end - line_start;
18801886
}
18811887
let mut unhighlighted_lines = Vec::new();
1888+
let mut last_pos = 0;
1889+
let mut is_item_attribute = false;
18821890
for (line_pos, (line, highlight_parts)) in lines.by_ref().zip(highlights).enumerate() {
1891+
last_pos = line_pos;
18831892
debug!(%line_pos, %line, ?highlight_parts);
18841893

18851894
// Remember lines that are not highlighted to hide them if needed
18861895
if highlight_parts.is_empty() {
18871896
unhighlighted_lines.push((line_pos, line));
18881897
continue;
18891898
}
1899+
if highlight_parts.len() == 1
1900+
&& line.trim().starts_with("#[")
1901+
&& line.trim().ends_with(']')
1902+
{
1903+
is_item_attribute = true;
1904+
}
18901905

18911906
match unhighlighted_lines.len() {
18921907
0 => (),
@@ -1963,13 +1978,41 @@ impl EmitterWriter {
19631978
is_multiline,
19641979
)
19651980
}
1981+
if let DisplaySuggestion::Add = show_code_change && is_item_attribute {
1982+
// The suggestion adds an entire line of code, ending on a newline, so we'll also
1983+
// print the *following* line, to provide context of what we're advicing people to
1984+
// do. Otherwise you would only see contextless code that can be confused for
1985+
// already existing code, despite the colors and UI elements.
1986+
// We special case `#[derive(_)]\n` and other attribute suggestions, because those
1987+
// are the ones where context is most useful.
1988+
let file_lines = sm
1989+
.span_to_lines(span.primary_span().unwrap().shrink_to_hi())
1990+
.expect("span_to_lines failed when emitting suggestion");
1991+
let line_num = sm.lookup_char_pos(parts[0].span.lo()).line;
1992+
if let Some(line) = file_lines.file.get_line(line_num - 1) {
1993+
let line = normalize_whitespace(&line);
1994+
self.draw_code_line(
1995+
&mut buffer,
1996+
&mut row_num,
1997+
&[],
1998+
line_num + last_pos + 1,
1999+
&line,
2000+
DisplaySuggestion::None,
2001+
max_line_num_len,
2002+
&file_lines,
2003+
is_multiline,
2004+
)
2005+
}
2006+
}
19662007

19672008
// This offset and the ones below need to be signed to account for replacement code
19682009
// that is shorter than the original code.
19692010
let mut offsets: Vec<(usize, isize)> = Vec::new();
19702011
// Only show an underline in the suggestions if the suggestion is not the
19712012
// entirety of the code being shown and the displayed code is not multiline.
1972-
if let DisplaySuggestion::Diff | DisplaySuggestion::Underline = show_code_change {
2013+
if let DisplaySuggestion::Diff | DisplaySuggestion::Underline | DisplaySuggestion::Add =
2014+
show_code_change
2015+
{
19732016
draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1);
19742017
for part in parts {
19752018
let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display;
@@ -2247,6 +2290,10 @@ impl EmitterWriter {
22472290
}
22482291
}
22492292
buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
2293+
} else if let DisplaySuggestion::Add = show_code_change {
2294+
buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
2295+
buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition);
2296+
buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
22502297
} else {
22512298
buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
22522299
draw_col_separator(buffer, *row_num, max_line_num_len + 1);
@@ -2281,6 +2328,7 @@ enum DisplaySuggestion {
22812328
Underline,
22822329
Diff,
22832330
None,
2331+
Add,
22842332
}
22852333

22862334
impl FileWithAnnotatedLines {

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ 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;
1010
|
11-
LL | use serde::__private::PhantomData;
11+
LL + use serde::__private::PhantomData;
1212
|
13-
LL | use std::marker::PhantomData;
13+
LL + use std::marker::PhantomData;
1414
|
1515

1616
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
|

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ 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;
1111
|
1212

1313
error: aborting due to previous error

tests/ui/coherence/coherence_inherent_cc.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ 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;
1111
|
1212

1313
error: aborting due to previous error

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +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)]
11+
LL + #![feature(generic_const_exprs)]
1212
|
1313

1414
error: aborting due to previous error

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ 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;
1010
|
11-
LL | use std::collections::binary_heap::IntoIter;
11+
LL + use std::collections::binary_heap::IntoIter;
1212
|
13-
LL | use std::collections::btree_map::IntoIter;
13+
LL + use std::collections::btree_map::IntoIter;
1414
|
15-
LL | use std::collections::btree_set::IntoIter;
15+
LL + use std::collections::btree_set::IntoIter;
1616
|
1717
and 8 other candidates
1818

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

tests/ui/consts/const-blocks/migrate-fail.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
88
= note: the `Copy` trait is required because this value will be copied for each element of the array
99
help: consider annotating `Bar` with `#[derive(Copy)]`
1010
|
11-
LL | #[derive(Copy)]
11+
LL + #[derive(Copy)]
12+
LL | struct Bar;
1213
|
1314

1415
error[E0277]: the trait bound `Bar: Copy` is not satisfied
@@ -21,7 +22,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
2122
= note: the `Copy` trait is required because this value will be copied for each element of the array
2223
help: consider annotating `Bar` with `#[derive(Copy)]`
2324
|
24-
LL | #[derive(Copy)]
25+
LL + #[derive(Copy)]
26+
LL | struct Bar;
2527
|
2628

2729
error: aborting due to 2 previous errors

tests/ui/consts/const-blocks/nll-fail.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
88
= note: the `Copy` trait is required because this value will be copied for each element of the array
99
help: consider annotating `Bar` with `#[derive(Copy)]`
1010
|
11-
LL | #[derive(Copy)]
11+
LL + #[derive(Copy)]
12+
LL | struct Bar;
1213
|
1314

1415
error[E0277]: the trait bound `Bar: Copy` is not satisfied
@@ -21,7 +22,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2];
2122
= note: the `Copy` trait is required because this value will be copied for each element of the array
2223
help: consider annotating `Bar` with `#[derive(Copy)]`
2324
|
24-
LL | #[derive(Copy)]
25+
LL + #[derive(Copy)]
26+
LL | struct Bar;
2527
|
2628

2729
error: aborting due to 2 previous errors

0 commit comments

Comments
 (0)