Suggest removing unused tuple fields if they are the last fields
This commit is contained in:
parent
47314eb427
commit
012a458dca
5 changed files with 111 additions and 47 deletions
|
@ -597,6 +597,15 @@ passes_pass_by_value =
|
||||||
|
|
||||||
passes_proc_macro_bad_sig = {$kind} has incorrect signature
|
passes_proc_macro_bad_sig = {$kind} has incorrect signature
|
||||||
|
|
||||||
|
passes_remove_fields =
|
||||||
|
consider removing { $num ->
|
||||||
|
[one] this
|
||||||
|
*[other] these
|
||||||
|
} { $num ->
|
||||||
|
[one] field
|
||||||
|
*[other] fields
|
||||||
|
}
|
||||||
|
|
||||||
passes_repr_conflicting =
|
passes_repr_conflicting =
|
||||||
conflicting representation hints
|
conflicting representation hints
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,7 @@ use rustc_target::abi::FieldIdx;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
ChangeFieldsToBeOfUnitType, IgnoredDerivedImpls, MultipleDeadCodes, ParentInfo,
|
ChangeFields, IgnoredDerivedImpls, MultipleDeadCodes, ParentInfo, UselessAssignment,
|
||||||
UselessAssignment,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Any local node that may call something in its body block should be
|
// Any local node that may call something in its body block should be
|
||||||
|
@ -993,17 +992,50 @@ impl<'tcx> DeadVisitor<'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let diag = match report_on {
|
let diag = match report_on {
|
||||||
ReportOn::TupleField => MultipleDeadCodes::UnusedTupleStructFields {
|
ReportOn::TupleField => {
|
||||||
multiple,
|
let tuple_fields = if let Some(parent_id) = parent_item
|
||||||
num,
|
&& let node = tcx.hir_node_by_def_id(parent_id)
|
||||||
descr,
|
&& let hir::Node::Item(hir::Item {
|
||||||
participle,
|
kind: hir::ItemKind::Struct(hir::VariantData::Tuple(fields, _, _), _),
|
||||||
name_list,
|
..
|
||||||
change_fields_suggestion: ChangeFieldsToBeOfUnitType { num, spans: spans.clone() },
|
}) = node
|
||||||
parent_info,
|
{
|
||||||
ignored_derived_impls,
|
*fields
|
||||||
},
|
} else {
|
||||||
|
&[]
|
||||||
|
};
|
||||||
|
|
||||||
|
let trailing_tuple_fields = if tuple_fields.len() >= dead_codes.len() {
|
||||||
|
LocalDefIdSet::from_iter(
|
||||||
|
tuple_fields
|
||||||
|
.iter()
|
||||||
|
.skip(tuple_fields.len() - dead_codes.len())
|
||||||
|
.map(|f| f.def_id),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
LocalDefIdSet::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let fields_suggestion =
|
||||||
|
// Suggest removal if all tuple fields are at the end.
|
||||||
|
// Otherwise suggest removal or changing to unit type
|
||||||
|
if dead_codes.iter().all(|dc| trailing_tuple_fields.contains(&dc.def_id)) {
|
||||||
|
ChangeFields::Remove { num }
|
||||||
|
} else {
|
||||||
|
ChangeFields::ChangeToUnitTypeOrRemove { num, spans: spans.clone() }
|
||||||
|
};
|
||||||
|
|
||||||
|
MultipleDeadCodes::UnusedTupleStructFields {
|
||||||
|
multiple,
|
||||||
|
num,
|
||||||
|
descr,
|
||||||
|
participle,
|
||||||
|
name_list,
|
||||||
|
change_fields_suggestion: fields_suggestion,
|
||||||
|
parent_info,
|
||||||
|
ignored_derived_impls,
|
||||||
|
}
|
||||||
|
}
|
||||||
ReportOn::NamedField => MultipleDeadCodes::DeadCodes {
|
ReportOn::NamedField => MultipleDeadCodes::DeadCodes {
|
||||||
multiple,
|
multiple,
|
||||||
num,
|
num,
|
||||||
|
|
|
@ -1589,7 +1589,7 @@ pub enum MultipleDeadCodes<'tcx> {
|
||||||
participle: &'tcx str,
|
participle: &'tcx str,
|
||||||
name_list: DiagSymbolList,
|
name_list: DiagSymbolList,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
change_fields_suggestion: ChangeFieldsToBeOfUnitType,
|
change_fields_suggestion: ChangeFields,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
parent_info: Option<ParentInfo<'tcx>>,
|
parent_info: Option<ParentInfo<'tcx>>,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
|
@ -1616,11 +1616,18 @@ pub struct IgnoredDerivedImpls {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(passes_change_fields_to_be_of_unit_type, applicability = "has-placeholders")]
|
pub enum ChangeFields {
|
||||||
pub struct ChangeFieldsToBeOfUnitType {
|
#[multipart_suggestion(
|
||||||
pub num: usize,
|
passes_change_fields_to_be_of_unit_type,
|
||||||
#[suggestion_part(code = "()")]
|
applicability = "has-placeholders"
|
||||||
pub spans: Vec<Span>,
|
)]
|
||||||
|
ChangeToUnitTypeOrRemove {
|
||||||
|
num: usize,
|
||||||
|
#[suggestion_part(code = "()")]
|
||||||
|
spans: Vec<Span>,
|
||||||
|
},
|
||||||
|
#[help(passes_remove_fields)]
|
||||||
|
Remove { num: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
|
|
@ -5,15 +5,20 @@ use std::marker::PhantomData;
|
||||||
|
|
||||||
const LEN: usize = 4;
|
const LEN: usize = 4;
|
||||||
|
|
||||||
struct SingleUnused(i32, [u8; LEN], String);
|
struct UnusedAtTheEnd(i32, f32, [u8; LEN], String, u8);
|
||||||
//~^ ERROR: field `1` is never read
|
//~^ ERROR:fields `1`, `2`, `3`, and `4` are never read
|
||||||
//~| NOTE: field in this struct
|
|
||||||
//~| HELP: consider changing the field to be of unit type
|
|
||||||
|
|
||||||
struct MultipleUnused(i32, f32, String, u8);
|
|
||||||
//~^ ERROR: fields `0`, `1`, `2`, and `3` are never read
|
|
||||||
//~| NOTE: fields in this struct
|
//~| NOTE: fields in this struct
|
||||||
//~| HELP: consider changing the fields to be of unit type
|
//~| HELP: consider removing these fields
|
||||||
|
|
||||||
|
struct UnusedJustOneField(i32);
|
||||||
|
//~^ ERROR: field `0` is never read
|
||||||
|
//~| NOTE: field in this struct
|
||||||
|
//~| HELP: consider removing this field
|
||||||
|
|
||||||
|
struct UnusedInTheMiddle(i32, f32, String, u8, u32);
|
||||||
|
//~^ ERROR: fields `1`, `2`, and `4` are never read
|
||||||
|
//~| NOTE: fields in this struct
|
||||||
|
//~| HELP: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields
|
||||||
|
|
||||||
struct GoodUnit(());
|
struct GoodUnit(());
|
||||||
|
|
||||||
|
@ -23,15 +28,19 @@ struct Void;
|
||||||
struct GoodVoid(Void);
|
struct GoodVoid(Void);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let w = SingleUnused(42, [0, 1, 2, 3], "abc".to_string());
|
let u1 = UnusedAtTheEnd(42, 3.14, [0, 1, 2, 3], "def".to_string(), 4u8);
|
||||||
let _ = w.0;
|
let _ = u1.0;
|
||||||
let _ = w.2;
|
|
||||||
|
let _ = UnusedJustOneField(42);
|
||||||
|
|
||||||
|
let u2 = UnusedInTheMiddle(42, 3.14, "def".to_string(), 4u8, 5);
|
||||||
|
let _ = u2.0;
|
||||||
|
let _ = u2.3;
|
||||||
|
|
||||||
let m = MultipleUnused(42, 3.14, "def".to_string(), 4u8);
|
|
||||||
|
|
||||||
let gu = GoodUnit(());
|
let gu = GoodUnit(());
|
||||||
let gp = GoodPhantom(PhantomData);
|
let gp = GoodPhantom(PhantomData);
|
||||||
let gv = GoodVoid(Void);
|
let gv = GoodVoid(Void);
|
||||||
|
|
||||||
let _ = (gu, gp, gv, m);
|
let _ = (gu, gp, gv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,40 @@
|
||||||
error: field `1` is never read
|
error: fields `1`, `2`, `3`, and `4` are never read
|
||||||
--> $DIR/tuple-struct-field.rs:8:26
|
--> $DIR/tuple-struct-field.rs:8:28
|
||||||
|
|
|
|
||||||
LL | struct SingleUnused(i32, [u8; LEN], String);
|
LL | struct UnusedAtTheEnd(i32, f32, [u8; LEN], String, u8);
|
||||||
| ------------ ^^^^^^^^^
|
| -------------- ^^^ ^^^^^^^^^ ^^^^^^ ^^
|
||||||
| |
|
| |
|
||||||
| field in this struct
|
| fields in this struct
|
||||||
|
|
|
|
||||||
|
= help: consider removing these fields
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/tuple-struct-field.rs:1:9
|
--> $DIR/tuple-struct-field.rs:1:9
|
||||||
|
|
|
|
||||||
LL | #![deny(dead_code)]
|
LL | #![deny(dead_code)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
|
|
||||||
|
|
|
||||||
LL | struct SingleUnused(i32, (), String);
|
|
||||||
| ~~
|
|
||||||
|
|
||||||
error: fields `0`, `1`, `2`, and `3` are never read
|
error: field `0` is never read
|
||||||
--> $DIR/tuple-struct-field.rs:13:23
|
--> $DIR/tuple-struct-field.rs:13:27
|
||||||
|
|
|
|
||||||
LL | struct MultipleUnused(i32, f32, String, u8);
|
LL | struct UnusedJustOneField(i32);
|
||||||
| -------------- ^^^ ^^^ ^^^^^^ ^^
|
| ------------------ ^^^
|
||||||
|
| |
|
||||||
|
| field in this struct
|
||||||
|
|
|
||||||
|
= help: consider removing this field
|
||||||
|
|
||||||
|
error: fields `1`, `2`, and `4` are never read
|
||||||
|
--> $DIR/tuple-struct-field.rs:18:31
|
||||||
|
|
|
||||||
|
LL | struct UnusedInTheMiddle(i32, f32, String, u8, u32);
|
||||||
|
| ----------------- ^^^ ^^^^^^ ^^^
|
||||||
| |
|
| |
|
||||||
| fields in this struct
|
| fields in this struct
|
||||||
|
|
|
|
||||||
help: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields
|
help: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields
|
||||||
|
|
|
|
||||||
LL | struct MultipleUnused((), (), (), ());
|
LL | struct UnusedInTheMiddle(i32, (), (), u8, ());
|
||||||
| ~~ ~~ ~~ ~~
|
| ~~ ~~ ~~
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue