Detect unused structs which derived Default
This commit is contained in:
parent
336e6ab3b3
commit
6997b6876d
@ -400,6 +400,31 @@ fn should_ignore_item(&mut self, def_id: DefId) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't ignore impls for Enums and pub Structs whose methods don't have self receiver,
|
||||
// cause external crate may call such methods to construct values of these types
|
||||
if let Some(local_impl_of) = impl_of.as_local()
|
||||
&& let Some(local_def_id) = def_id.as_local()
|
||||
&& let Some(fn_sig) =
|
||||
self.tcx.hir().fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id))
|
||||
&& matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None)
|
||||
&& let TyKind::Path(hir::QPath::Resolved(_, path)) =
|
||||
self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind
|
||||
&& let Res::Def(def_kind, did) = path.res
|
||||
{
|
||||
match def_kind {
|
||||
// for example, #[derive(Default)] pub struct T(i32);
|
||||
// external crate can call T::default() to construct T,
|
||||
// so that don't ignore impl Default for pub Enum and Structs
|
||||
DefKind::Struct | DefKind::Union if self.tcx.visibility(did).is_public() => {
|
||||
return false;
|
||||
}
|
||||
// don't ignore impl Default for Enums,
|
||||
// cause we don't know which variant is constructed
|
||||
DefKind::Enum => return false,
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
|
||||
&& self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads)
|
||||
{
|
||||
|
@ -396,7 +396,7 @@ fn show_arc() {
|
||||
|
||||
// Make sure deriving works with Arc<T>
|
||||
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
|
||||
struct Foo {
|
||||
struct _Foo {
|
||||
inner: Arc<i32>,
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,7 @@
|
||||
/// ```
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "Default")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
|
||||
pub trait Default: Sized {
|
||||
/// Returns the "default value" for a type.
|
||||
///
|
||||
|
@ -22,6 +22,6 @@ enum MyOption<T> {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(Foo::default(), Foo::Alpha);
|
||||
assert!(matches!(Foo::default(), Foo::Alpha));
|
||||
assert!(matches!(MyOption::<NotDefault>::default(), MyOption::None));
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
use std::panic::catch_unwind;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default)]
|
||||
struct Guard;
|
||||
|
||||
|
25
tests/ui/lint/dead-code/unused-struct-derive-default.rs
Normal file
25
tests/ui/lint/dead-code/unused-struct-derive-default.rs
Normal file
@ -0,0 +1,25 @@
|
||||
#![deny(dead_code)]
|
||||
|
||||
#[derive(Default)]
|
||||
struct T; //~ ERROR struct `T` is never constructed
|
||||
|
||||
#[derive(Default)]
|
||||
struct Used;
|
||||
|
||||
#[derive(Default)]
|
||||
enum E {
|
||||
#[default]
|
||||
A,
|
||||
B, //~ ERROR variant `B` is never constructed
|
||||
}
|
||||
|
||||
// external crate can call T2::default() to construct T2,
|
||||
// so that no warnings for pub adts
|
||||
#[derive(Default)]
|
||||
pub struct T2 {
|
||||
_unread: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _x: Used = Default::default();
|
||||
}
|
24
tests/ui/lint/dead-code/unused-struct-derive-default.stderr
Normal file
24
tests/ui/lint/dead-code/unused-struct-derive-default.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
error: struct `T` is never constructed
|
||||
--> $DIR/unused-struct-derive-default.rs:4:8
|
||||
|
|
||||
LL | struct T;
|
||||
| ^
|
||||
|
|
||||
= note: `T` has a derived impl for the trait `Default`, but this is intentionally ignored during dead code analysis
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused-struct-derive-default.rs:1:9
|
||||
|
|
||||
LL | #![deny(dead_code)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: variant `B` is never constructed
|
||||
--> $DIR/unused-struct-derive-default.rs:13:5
|
||||
|
|
||||
LL | enum E {
|
||||
| - variant in this enum
|
||||
...
|
||||
LL | B,
|
||||
| ^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user