1
Fork 0

Suggest removing unused tuple fields if they are the last fields

This commit is contained in:
Gurinder Singh 2024-05-13 17:42:44 +05:30
parent 47314eb427
commit 012a458dca
5 changed files with 111 additions and 47 deletions

View file

@ -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

View file

@ -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,

View file

@ -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)]

View file

@ -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);
} }

View file

@ -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