Rollup merge of #100031 - GoldsteinE:try-removing-the-field, r=michaelwoerister
improve "try ignoring the field" diagnostic Closes #95795
This commit is contained in:
commit
710bd23df1
6 changed files with 89 additions and 3 deletions
|
@ -98,7 +98,7 @@ use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::{self, DefIdTree, RootVariableMinCaptureList, Ty, TyCtxt};
|
use rustc_middle::ty::{self, DefIdTree, RootVariableMinCaptureList, Ty, TyCtxt};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::symbol::{kw, sym, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::{BytePos, Span};
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
@ -1549,6 +1549,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
|
||||||
.or_insert_with(|| (ln, var, vec![id_and_sp]));
|
.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 {
|
for (_, (ln, var, hir_ids_and_spans)) in vars {
|
||||||
if self.used_on_entry(ln, var) {
|
if self.used_on_entry(ln, var) {
|
||||||
let id = hir_ids_and_spans[0].0;
|
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();
|
hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect();
|
||||||
on_used_on_entry(spans, id, ln, var);
|
on_used_on_entry(spans, id, ln, var);
|
||||||
} else {
|
} 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(
|
fn report_unused(
|
||||||
&self,
|
&self,
|
||||||
hir_ids_and_spans: Vec<(HirId, Span, Span)>,
|
hir_ids_and_spans: Vec<(HirId, Span, Span)>,
|
||||||
ln: LiveNode,
|
ln: LiveNode,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
|
can_remove: bool,
|
||||||
) {
|
) {
|
||||||
let first_hir_id = hir_ids_and_spans[0].0;
|
let first_hir_id = hir_ids_and_spans[0].0;
|
||||||
|
|
||||||
|
@ -1590,6 +1594,32 @@ impl<'tcx> Liveness<'_, 'tcx> {
|
||||||
.emit();
|
.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 {
|
} else {
|
||||||
let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
|
let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
|
||||||
hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| {
|
hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| {
|
||||||
|
|
|
@ -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 {
|
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) {
|
if let Ok(next_source) = self.span_to_next_source(sp) {
|
||||||
let next_source = next_source.split(c).next().unwrap_or("");
|
let next_source = next_source.split(c).next().unwrap_or("");
|
||||||
|
|
17
src/test/ui/suggestions/dont-try-removing-the-field.rs
Normal file
17
src/test/ui/suggestions/dont-try-removing-the-field.rs
Normal 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() {}
|
10
src/test/ui/suggestions/dont-try-removing-the-field.stderr
Normal file
10
src/test/ui/suggestions/dont-try-removing-the-field.stderr
Normal 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
|
||||||
|
|
17
src/test/ui/suggestions/try-removing-the-field.rs
Normal file
17
src/test/ui/suggestions/try-removing-the-field.rs
Normal 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() {}
|
12
src/test/ui/suggestions/try-removing-the-field.stderr
Normal file
12
src/test/ui/suggestions/try-removing-the-field.stderr
Normal 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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue