diff options
| author | Goldstein <root@goldstein.rs> | 2022-08-01 21:49:12 +0300 |
|---|---|---|
| committer | Goldstein <root@goldstein.rs> | 2022-08-12 12:32:43 +0300 |
| commit | 3fb249bebce995ec6fdb1a4a3f49cf1acd5c86b7 (patch) | |
| tree | 545c11acc986f95dd8afb2610647974cfdeabf59 | |
| parent | f03ce30962cf1b2a5158667eabae8bf6e8d1cb03 (diff) | |
| download | rust-3fb249bebce995ec6fdb1a4a3f49cf1acd5c86b7.tar.gz rust-3fb249bebce995ec6fdb1a4a3f49cf1acd5c86b7.zip | |
improve "try ignoring the field" diagnostic
Closes #95795
| -rw-r--r-- | compiler/rustc_passes/src/liveness.rs | 34 | ||||
| -rw-r--r-- | src/test/ui/suggestions/dont-try-removing-the-field.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/suggestions/dont-try-removing-the-field.stderr | 10 | ||||
| -rw-r--r-- | src/test/ui/suggestions/try-removing-the-field.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/suggestions/try-removing-the-field.stderr | 12 |
5 files changed, 88 insertions, 2 deletions
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 461dd52b9f2..7124b84bfef 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -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)| { diff --git a/src/test/ui/suggestions/dont-try-removing-the-field.rs b/src/test/ui/suggestions/dont-try-removing-the-field.rs new file mode 100644 index 00000000000..948aa2b94d9 --- /dev/null +++ b/src/test/ui/suggestions/dont-try-removing-the-field.rs @@ -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() {} diff --git a/src/test/ui/suggestions/dont-try-removing-the-field.stderr b/src/test/ui/suggestions/dont-try-removing-the-field.stderr new file mode 100644 index 00000000000..263171a4ac4 --- /dev/null +++ b/src/test/ui/suggestions/dont-try-removing-the-field.stderr @@ -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 + diff --git a/src/test/ui/suggestions/try-removing-the-field.rs b/src/test/ui/suggestions/try-removing-the-field.rs new file mode 100644 index 00000000000..9d0573ca255 --- /dev/null +++ b/src/test/ui/suggestions/try-removing-the-field.rs @@ -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() {} diff --git a/src/test/ui/suggestions/try-removing-the-field.stderr b/src/test/ui/suggestions/try-removing-the-field.stderr new file mode 100644 index 00000000000..448a2c3d2ec --- /dev/null +++ b/src/test/ui/suggestions/try-removing-the-field.stderr @@ -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 + |
