Skip to content

Commit d3d31e3

Browse files
committed
Detect unused structs which derived Default
1 parent 336e6ab commit d3d31e3

File tree

6 files changed

+44
-2
lines changed

6 files changed

+44
-2
lines changed

compiler/rustc_passes/src/dead.rs

+15
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,21 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
400400
return false;
401401
}
402402

403+
// don't ignore the impl Default for Enum,
404+
// cause we don't know which variant is constructed
405+
if let Some(local_impl_of) = impl_of.as_local()
406+
&& let Some(local_def_id) = def_id.as_local()
407+
&& let TyKind::Path(hir::QPath::Resolved(_, path)) =
408+
self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind
409+
&& let Res::Def(DefKind::Enum, did) = path.res
410+
&& did.is_local()
411+
&& let Some(fn_sig) =
412+
self.tcx.hir().fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id))
413+
&& matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None)
414+
{
415+
return false;
416+
}
417+
403418
if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
404419
&& self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads)
405420
{

library/alloc/src/sync/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ fn show_arc() {
396396

397397
// Make sure deriving works with Arc<T>
398398
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
399-
struct Foo {
399+
struct _Foo {
400400
inner: Arc<i32>,
401401
}
402402

library/core/src/default.rs

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ use crate::ascii::Char as AsciiChar;
103103
/// ```
104104
#[cfg_attr(not(test), rustc_diagnostic_item = "Default")]
105105
#[stable(feature = "rust1", since = "1.0.0")]
106+
#[rustc_trivial_field_reads]
106107
pub trait Default: Sized {
107108
/// Returns the "default value" for a type.
108109
///

tests/ui/deriving/deriving-default-enum.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ enum MyOption<T> {
2222
}
2323

2424
fn main() {
25-
assert_eq!(Foo::default(), Foo::Alpha);
25+
assert!(matches!(Foo::default(), Foo::Alpha));
2626
assert!(matches!(MyOption::<NotDefault>::default(), MyOption::None));
2727
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![deny(dead_code)]
2+
3+
#[derive(Default)]
4+
struct T; //~ ERROR struct `T` is never constructed
5+
6+
#[derive(Default)]
7+
struct Used;
8+
9+
fn main() {
10+
let _x: Used = Default::default();
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: struct `T` is never constructed
2+
--> $DIR/unused-struct-derive-default.rs:4:8
3+
|
4+
LL | struct T;
5+
| ^
6+
|
7+
= note: `T` has a derived impl for the trait `Default`, but this is intentionally ignored during dead code analysis
8+
note: the lint level is defined here
9+
--> $DIR/unused-struct-derive-default.rs:1:9
10+
|
11+
LL | #![deny(dead_code)]
12+
| ^^^^^^^^^
13+
14+
error: aborting due to 1 previous error
15+

0 commit comments

Comments
 (0)