Skip to content

Commit d1d57bd

Browse files
authored
Rollup merge of rust-lang#126818 - estebank:suggestions-fix, r=wesleywiser
Better handle suggestions for the already present code and fix some suggestions When a suggestion part is for code that is already present, skip it. If all the suggestion parts for a suggestion are for code that is already there, do not emit the suggestion. Fix two suggestions that treat `span_suggestion` as if it were `span_help`.
2 parents 425ae69 + 8ce8c42 commit d1d57bd

12 files changed

+75
-58
lines changed

compiler/rustc_errors/src/emitter.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,10 @@ impl HumanEmitter {
17671767
debug!(?suggestions);
17681768

17691769
if suggestions.is_empty() {
1770-
// Suggestions coming from macros can have malformed spans. This is a heavy handed
1770+
// Here we check if there are suggestions that have actual code changes. We sometimes
1771+
// suggest the same code that is already there, instead of changing how we produce the
1772+
// suggestions and filtering there, we just don't emit the suggestion.
1773+
// Suggestions coming from macros can also have malformed spans. This is a heavy handed
17711774
// approach to avoid ICEs by ignoring the suggestion outright.
17721775
return Ok(());
17731776
}
@@ -2046,7 +2049,9 @@ impl HumanEmitter {
20462049
assert!(underline_start >= 0 && underline_end >= 0);
20472050
let padding: usize = max_line_num_len + 3;
20482051
for p in underline_start..underline_end {
2049-
if let DisplaySuggestion::Underline = show_code_change {
2052+
if let DisplaySuggestion::Underline = show_code_change
2053+
&& is_different(sm, &part.snippet, part.span)
2054+
{
20502055
// If this is a replacement, underline with `~`, if this is an addition
20512056
// underline with `+`.
20522057
buffer.putc(
@@ -2824,6 +2829,18 @@ impl Style {
28242829
}
28252830
}
28262831

2832+
/// Whether the original and suggested code are the same.
2833+
pub fn is_different(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
2834+
let found = match sm.span_to_snippet(sp) {
2835+
Ok(snippet) => snippet,
2836+
Err(e) => {
2837+
warn!(error = ?e, "Invalid span {:?}", sp);
2838+
return true;
2839+
}
2840+
};
2841+
found != suggested
2842+
}
2843+
28272844
/// Whether the original and suggested code are visually similar enough to warrant extra wording.
28282845
pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
28292846
// FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode.

compiler/rustc_errors/src/lib.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub use diagnostic_impls::{
5050
IndicateAnonymousLifetime, SingleLabelManySpans,
5151
};
5252
pub use emitter::ColorConfig;
53-
use emitter::{is_case_difference, DynEmitter, Emitter};
53+
use emitter::{is_case_difference, is_different, DynEmitter, Emitter};
5454
use registry::Registry;
5555
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
5656
use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
@@ -357,10 +357,16 @@ impl CodeSuggestion {
357357
_ => 1,
358358
})
359359
.sum();
360-
line_highlight.push(SubstitutionHighlight {
361-
start: (cur_lo.col.0 as isize + acc) as usize,
362-
end: (cur_lo.col.0 as isize + acc + len) as usize,
363-
});
360+
if !is_different(sm, &part.snippet, part.span) {
361+
// Account for cases where we are suggesting the same code that's already
362+
// there. This shouldn't happen often, but in some cases for multipart
363+
// suggestions it's much easier to handle it here than in the origin.
364+
} else {
365+
line_highlight.push(SubstitutionHighlight {
366+
start: (cur_lo.col.0 as isize + acc) as usize,
367+
end: (cur_lo.col.0 as isize + acc + len) as usize,
368+
});
369+
}
364370
buf.push_str(&part.snippet);
365371
let cur_hi = sm.lookup_char_pos(part.span.hi());
366372
// Account for the difference between the width of the current code and the
@@ -392,7 +398,11 @@ impl CodeSuggestion {
392398
while buf.ends_with('\n') {
393399
buf.pop();
394400
}
395-
Some((buf, substitution.parts, highlights, only_capitalization))
401+
if highlights.iter().all(|parts| parts.is_empty()) {
402+
None
403+
} else {
404+
Some((buf, substitution.parts, highlights, only_capitalization))
405+
}
396406
})
397407
.collect()
398408
}

src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
145145
(
146146
"this function's return value is unnecessary".to_string(),
147147
"remove the return type...".to_string(),
148-
snippet(cx, fn_decl.output.span(), "..").to_string(),
148+
// FIXME: we should instead get the span including the `->` and suggest an
149+
// empty string for this case.
150+
"()".to_string(),
149151
"...and then remove returned values",
150152
)
151153
} else {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ LL | let _val = None::<()>.expect("this always happens");
6363
help: remove the `None` and `expect()`
6464
|
6565
LL | let _val = panic!("this always happens");
66-
| ~~~~~~~ ~
66+
| ~~~~~~~
6767

6868
error: used `unwrap_or_default()` on `None` value
6969
--> tests/ui/unnecessary_literal_unwrap.rs:22:24
@@ -134,7 +134,7 @@ LL | None::<()>.expect("this always happens");
134134
help: remove the `None` and `expect()`
135135
|
136136
LL | panic!("this always happens");
137-
| ~~~~~~~ ~
137+
| ~~~~~~~
138138

139139
error: used `unwrap_or_default()` on `None` value
140140
--> tests/ui/unnecessary_literal_unwrap.rs:30:5

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ LL | | }
118118
|
119119
help: remove the return type...
120120
|
121-
LL | fn issue_6640_1(a: bool, b: bool) -> Option<()> {
122-
| ~~~~~~~~~~
121+
LL | fn issue_6640_1(a: bool, b: bool) -> () {
122+
| ~~
123123
help: ...and then remove returned values
124124
|
125125
LL ~ return ;
@@ -145,8 +145,8 @@ LL | | }
145145
|
146146
help: remove the return type...
147147
|
148-
LL | fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {
149-
| ~~~~~~~~~~~~~~~
148+
LL | fn issue_6640_2(a: bool, b: bool) -> () {
149+
| ~~
150150
help: ...and then remove returned values
151151
|
152152
LL ~ return ;

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

-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ error[E0282]: type annotations needed
44
LL | Combination::<0>.and::<_>().and::<_>();
55
| ^^^ cannot infer type of the type parameter `M` declared on the method `and`
66
|
7-
help: consider specifying the generic argument
8-
|
9-
LL | Combination::<0>.and::<_>().and::<_>();
10-
| ~~~~~
117

128
error: aborting due to 1 previous error
139

tests/ui/imports/issue-55884-2.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ note: ...and refers to the struct `ParseOptions` which is defined here
2424
|
2525
LL | pub struct ParseOptions {}
2626
| ^^^^^^^^^^^^^^^^^^^^^^^ you could import this directly
27-
help: import `ParseOptions` through the re-export
28-
|
29-
LL | pub use parser::ParseOptions;
30-
| ~~~~~~~~~~~~~~~~~~~~
3127

3228
error: aborting due to 1 previous error
3329

tests/ui/lint/wide_pointer_comparisons.stderr

+19-19
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ LL | let _ = PartialEq::eq(&a, &b);
7474
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
7575
|
7676
LL | let _ = std::ptr::addr_eq(a, b);
77-
| ~~~~~~~~~~~~~~~~~~ ~ ~
77+
| ~~~~~~~~~~~~~~~~~~ ~
7878

7979
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
8080
--> $DIR/wide_pointer_comparisons.rs:35:13
@@ -85,7 +85,7 @@ LL | let _ = PartialEq::ne(&a, &b);
8585
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
8686
|
8787
LL | let _ = !std::ptr::addr_eq(a, b);
88-
| ~~~~~~~~~~~~~~~~~~~ ~ ~
88+
| ~~~~~~~~~~~~~~~~~~~ ~
8989

9090
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
9191
--> $DIR/wide_pointer_comparisons.rs:37:13
@@ -96,7 +96,7 @@ LL | let _ = a.eq(&b);
9696
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
9797
|
9898
LL | let _ = std::ptr::addr_eq(a, b);
99-
| ++++++++++++++++++ ~ ~
99+
| ++++++++++++++++++ ~
100100

101101
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
102102
--> $DIR/wide_pointer_comparisons.rs:39:13
@@ -107,7 +107,7 @@ LL | let _ = a.ne(&b);
107107
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
108108
|
109109
LL | let _ = !std::ptr::addr_eq(a, b);
110-
| +++++++++++++++++++ ~ ~
110+
| +++++++++++++++++++ ~
111111

112112
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
113113
--> $DIR/wide_pointer_comparisons.rs:41:13
@@ -283,7 +283,7 @@ LL | let _ = PartialEq::eq(a, b);
283283
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
284284
|
285285
LL | let _ = std::ptr::addr_eq(*a, *b);
286-
| ~~~~~~~~~~~~~~~~~~~ ~~~ ~
286+
| ~~~~~~~~~~~~~~~~~~~ ~~~
287287

288288
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
289289
--> $DIR/wide_pointer_comparisons.rs:85:17
@@ -294,7 +294,7 @@ LL | let _ = PartialEq::ne(a, b);
294294
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
295295
|
296296
LL | let _ = !std::ptr::addr_eq(*a, *b);
297-
| ~~~~~~~~~~~~~~~~~~~~ ~~~ ~
297+
| ~~~~~~~~~~~~~~~~~~~~ ~~~
298298

299299
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
300300
--> $DIR/wide_pointer_comparisons.rs:87:17
@@ -305,7 +305,7 @@ LL | let _ = PartialEq::eq(&a, &b);
305305
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
306306
|
307307
LL | let _ = std::ptr::addr_eq(*a, *b);
308-
| ~~~~~~~~~~~~~~~~~~~ ~~~ ~
308+
| ~~~~~~~~~~~~~~~~~~~ ~~~
309309

310310
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
311311
--> $DIR/wide_pointer_comparisons.rs:89:17
@@ -316,7 +316,7 @@ LL | let _ = PartialEq::ne(&a, &b);
316316
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
317317
|
318318
LL | let _ = !std::ptr::addr_eq(*a, *b);
319-
| ~~~~~~~~~~~~~~~~~~~~ ~~~ ~
319+
| ~~~~~~~~~~~~~~~~~~~~ ~~~
320320

321321
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
322322
--> $DIR/wide_pointer_comparisons.rs:91:17
@@ -327,7 +327,7 @@ LL | let _ = a.eq(b);
327327
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
328328
|
329329
LL | let _ = std::ptr::addr_eq(*a, *b);
330-
| +++++++++++++++++++ ~~~ ~
330+
| +++++++++++++++++++ ~~~
331331

332332
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
333333
--> $DIR/wide_pointer_comparisons.rs:93:17
@@ -338,7 +338,7 @@ LL | let _ = a.ne(b);
338338
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
339339
|
340340
LL | let _ = !std::ptr::addr_eq(*a, *b);
341-
| ++++++++++++++++++++ ~~~ ~
341+
| ++++++++++++++++++++ ~~~
342342

343343
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
344344
--> $DIR/wide_pointer_comparisons.rs:95:17
@@ -519,11 +519,11 @@ LL | let _ = PartialEq::eq(&a, &b);
519519
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
520520
|
521521
LL | let _ = std::ptr::addr_eq(a, b);
522-
| ~~~~~~~~~~~~~~~~~~ ~ ~
522+
| ~~~~~~~~~~~~~~~~~~ ~
523523
help: use explicit `std::ptr::eq` method to compare metadata and addresses
524524
|
525525
LL | let _ = std::ptr::eq(a, b);
526-
| ~~~~~~~~~~~~~ ~ ~
526+
| ~~~~~~~~~~~~~ ~
527527

528528
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
529529
--> $DIR/wide_pointer_comparisons.rs:133:17
@@ -534,11 +534,11 @@ LL | let _ = PartialEq::ne(&a, &b);
534534
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
535535
|
536536
LL | let _ = !std::ptr::addr_eq(a, b);
537-
| ~~~~~~~~~~~~~~~~~~~ ~ ~
537+
| ~~~~~~~~~~~~~~~~~~~ ~
538538
help: use explicit `std::ptr::eq` method to compare metadata and addresses
539539
|
540540
LL | let _ = !std::ptr::eq(a, b);
541-
| ~~~~~~~~~~~~~~ ~ ~
541+
| ~~~~~~~~~~~~~~ ~
542542

543543
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
544544
--> $DIR/wide_pointer_comparisons.rs:135:17
@@ -549,11 +549,11 @@ LL | let _ = a.eq(&b);
549549
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
550550
|
551551
LL | let _ = std::ptr::addr_eq(a, b);
552-
| ++++++++++++++++++ ~ ~
552+
| ++++++++++++++++++ ~
553553
help: use explicit `std::ptr::eq` method to compare metadata and addresses
554554
|
555555
LL | let _ = std::ptr::eq(a, b);
556-
| +++++++++++++ ~ ~
556+
| +++++++++++++ ~
557557

558558
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
559559
--> $DIR/wide_pointer_comparisons.rs:137:17
@@ -564,11 +564,11 @@ LL | let _ = a.ne(&b);
564564
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
565565
|
566566
LL | let _ = !std::ptr::addr_eq(a, b);
567-
| +++++++++++++++++++ ~ ~
567+
| +++++++++++++++++++ ~
568568
help: use explicit `std::ptr::eq` method to compare metadata and addresses
569569
|
570570
LL | let _ = !std::ptr::eq(a, b);
571-
| ++++++++++++++ ~ ~
571+
| ++++++++++++++ ~
572572

573573
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
574574
--> $DIR/wide_pointer_comparisons.rs:142:9
@@ -594,7 +594,7 @@ LL | cmp!(a, b);
594594
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
595595
|
596596
LL | cmp!(std::ptr::addr_eq(a, b));
597-
| ++++++++++++++++++ ~ +
597+
| ++++++++++++++++++ +
598598

599599
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
600600
--> $DIR/wide_pointer_comparisons.rs:159:39

tests/ui/privacy/issue-75907.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ LL | let Bar(x, y, Foo(z)) = make_bar();
1414
help: consider making the fields publicly accessible
1515
|
1616
LL | pub(crate) struct Bar(pub u8, pub u8, pub Foo);
17-
| ~~~ ~~~ +++
17+
| ~~~ +++
1818

1919
error[E0532]: cannot match against a tuple struct which contains private fields
2020
--> $DIR/issue-75907.rs:15:19

0 commit comments

Comments
 (0)