Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit adf0dff

Browse files
committed
Not lint pub structs without pub constructors if containing fields of unit, never type, PhantomData and positional ZST
1 parent 355efac commit adf0dff

File tree

5 files changed

+83
-22
lines changed

5 files changed

+83
-22
lines changed

compiler/rustc_passes/src/dead.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,26 @@ fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
7272
}
7373

7474
fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: LocalDefId) -> bool {
75-
// treat PhantomData and positional ZST as public,
76-
// we don't want to lint types which only have them,
77-
// cause it's a common way to use such types to check things like well-formedness
78-
tcx.adt_def(id).all_fields().all(|field| {
75+
let adt_def = tcx.adt_def(id);
76+
77+
// skip types contain fields of unit and never type,
78+
// it's usually intentional to make the type not constructible
79+
let not_require_constructor = adt_def.all_fields().any(|field| {
7980
let field_type = tcx.type_of(field.did).instantiate_identity();
80-
if field_type.is_phantom_data() {
81-
return true;
82-
}
83-
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
84-
if is_positional
85-
&& tcx
86-
.layout_of(tcx.param_env(field.did).and(field_type))
87-
.map_or(true, |layout| layout.is_zst())
88-
{
89-
return true;
90-
}
91-
field.vis.is_public()
92-
})
81+
field_type.is_unit() || field_type.is_never()
82+
});
83+
84+
not_require_constructor
85+
|| adt_def.all_fields().all(|field| {
86+
let field_type = tcx.type_of(field.did).instantiate_identity();
87+
// skip fields of PhantomData,
88+
// cause it's a common way to check things like well-formedness
89+
if field_type.is_phantom_data() {
90+
return true;
91+
}
92+
93+
field.vis.is_public()
94+
})
9395
}
9496

9597
/// check struct and its fields are public or not,

tests/ui/derives/clone-debug-dead-code-in-the-same-struct.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#![forbid(dead_code)]
22

33
#[derive(Debug)]
4-
pub struct Whatever { //~ ERROR struct `Whatever` is never constructed
4+
pub struct Whatever {
55
pub field0: (),
6-
field1: (),
6+
field1: (), //~ ERROR fields `field1`, `field2`, `field3`, and `field4` are never read
77
field2: (),
88
field3: (),
99
field4: (),

tests/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
error: struct `Whatever` is never constructed
2-
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:4:12
1+
error: fields `field1`, `field2`, `field3`, and `field4` are never read
2+
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:6:5
33
|
44
LL | pub struct Whatever {
5-
| ^^^^^^^^
5+
| -------- fields in this struct
6+
LL | pub field0: (),
7+
LL | field1: (),
8+
| ^^^^^^
9+
LL | field2: (),
10+
| ^^^^^^
11+
LL | field3: (),
12+
| ^^^^^^
13+
LL | field4: (),
14+
| ^^^^^^
615
|
16+
= note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
717
note: the lint level is defined here
818
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:1:11
919
|
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![feature(never_type)]
2+
#![deny(dead_code)]
3+
4+
pub struct T1(!);
5+
pub struct T2(());
6+
pub struct T3<X>(std::marker::PhantomData<X>);
7+
8+
pub struct T4 {
9+
_x: !,
10+
}
11+
12+
pub struct T5<X> {
13+
_x: !,
14+
_y: X,
15+
}
16+
17+
pub struct T6 {
18+
_x: (),
19+
}
20+
21+
pub struct T7<X> {
22+
_x: (),
23+
_y: X,
24+
}
25+
26+
pub struct T8<X> {
27+
_x: std::marker::PhantomData<X>,
28+
}
29+
30+
pub struct T9<X> { //~ ERROR struct `T9` is never constructed
31+
_x: std::marker::PhantomData<X>,
32+
_y: i32,
33+
}
34+
35+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: struct `T9` is never constructed
2+
--> $DIR/unconstructible-pub-struct.rs:30:12
3+
|
4+
LL | pub struct T9<X> {
5+
| ^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/unconstructible-pub-struct.rs:2:9
9+
|
10+
LL | #![deny(dead_code)]
11+
| ^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

0 commit comments

Comments
 (0)