Rollup merge of #100031 - GoldsteinE:try-removing-the-field, r=michaelwoerister

improve "try ignoring the field" diagnostic

Closes #95795
This commit is contained in:
Matthias Krüger 2022-08-15 20:11:32 +02:00 committed by GitHub
commit 710bd23df1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 3 deletions

View File

@ -98,7 +98,7 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, DefIdTree, RootVariableMinCaptureList, Ty, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
use rustc_span::{BytePos, Span};
use std::collections::VecDeque;
use std::io;
@ -1549,6 +1549,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
.or_insert_with(|| (ln, var, vec![id_and_sp]));
});
let can_remove = matches!(&pat.kind, hir::PatKind::Struct(_, _, true));
for (_, (ln, var, hir_ids_and_spans)) in vars {
if self.used_on_entry(ln, var) {
let id = hir_ids_and_spans[0].0;
@ -1556,16 +1558,18 @@ impl<'tcx> Liveness<'_, 'tcx> {
hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect();
on_used_on_entry(spans, id, ln, var);
} else {
self.report_unused(hir_ids_and_spans, ln, var);
self.report_unused(hir_ids_and_spans, ln, var, can_remove);
}
}
}
#[tracing::instrument(skip(self), level = "INFO")]
fn report_unused(
&self,
hir_ids_and_spans: Vec<(HirId, Span, Span)>,
ln: LiveNode,
var: Variable,
can_remove: bool,
) {
let first_hir_id = hir_ids_and_spans[0].0;
@ -1590,6 +1594,32 @@ impl<'tcx> Liveness<'_, 'tcx> {
.emit();
},
)
} else if can_remove {
self.ir.tcx.struct_span_lint_hir(
lint::builtin::UNUSED_VARIABLES,
first_hir_id,
hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::<Vec<_>>(),
|lint| {
let mut err = lint.build(&format!("unused variable: `{}`", name));
err.multipart_suggestion(
"try removing the field",
hir_ids_and_spans
.iter()
.map(|(_, pat_span, _)| {
let span = self
.ir
.tcx
.sess
.source_map()
.span_extend_to_next_char(*pat_span, ',', true);
(span.with_hi(BytePos(span.hi().0 + 1)), String::new())
})
.collect(),
Applicability::MachineApplicable,
);
err.emit();
},
);
} else {
let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| {

View File

@ -722,7 +722,7 @@ impl SourceMap {
})
}
/// Extends the given `Span` to just after the next occurrence of `c`.
/// Extends the given `Span` to just before the next occurrence of `c`.
pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
if let Ok(next_source) = self.span_to_next_source(sp) {
let next_source = next_source.split(c).next().unwrap_or("");

View File

@ -0,0 +1,17 @@
// run-pass
#![allow(dead_code)]
struct Foo {
foo: i32,
bar: i32,
baz: (),
}
fn use_foo(x: Foo) -> (i32, i32) {
let Foo { foo, bar, baz } = x; //~ WARNING unused variable: `baz`
//~| help: try ignoring the field
return (foo, bar);
}
fn main() {}

View File

@ -0,0 +1,10 @@
warning: unused variable: `baz`
--> $DIR/dont-try-removing-the-field.rs:12:25
|
LL | let Foo { foo, bar, baz } = x;
| ^^^ help: try ignoring the field: `baz: _`
|
= note: `#[warn(unused_variables)]` on by default
warning: 1 warning emitted

View File

@ -0,0 +1,17 @@
// run-pass
#![allow(dead_code)]
struct Foo {
foo: i32,
bar: (),
baz: (),
}
fn use_foo(x: Foo) -> i32 {
let Foo { foo, bar, .. } = x; //~ WARNING unused variable: `bar`
//~| help: try removing the field
return foo;
}
fn main() {}

View File

@ -0,0 +1,12 @@
warning: unused variable: `bar`
--> $DIR/try-removing-the-field.rs:12:20
|
LL | let Foo { foo, bar, .. } = x;
| ^^^-
| |
| help: try removing the field
|
= note: `#[warn(unused_variables)]` on by default
warning: 1 warning emitted