Skip to content

Commit 7fcaefe

Browse files
committedJul 24, 2024·
Not lint pub structs without pub constructors if containing fields of unit, never type, PhantomData and positional ZST
1 parent 73a2281 commit 7fcaefe

File tree

5 files changed

+81
-22
lines changed

5 files changed

+81
-22
lines changed
 

‎compiler/rustc_passes/src/dead.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -55,24 +55,24 @@ impl Publicness {
5555
}
5656

5757
fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {
58-
// treat PhantomData and positional ZST as public,
59-
// we don't want to lint types which only have them,
60-
// cause it's a common way to use such types to check things like well-formedness
61-
tcx.adt_def(id).all_fields().all(|field| {
58+
// skip types contain fields of unit and never type,
59+
// it's usually intentional to make the type not constructible
60+
let not_require_constructor = tcx.adt_def(id).all_fields().any(|field| {
6261
let field_type = tcx.type_of(field.did).instantiate_identity();
63-
if field_type.is_phantom_data() {
64-
return true;
65-
}
66-
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
67-
if is_positional
68-
&& tcx
69-
.layout_of(tcx.param_env(field.did).and(field_type))
70-
.map_or(true, |layout| layout.is_zst())
71-
{
72-
return true;
73-
}
74-
field.vis.is_public()
75-
})
62+
field_type.is_unit() || field_type.is_never()
63+
});
64+
65+
not_require_constructor
66+
|| tcx.adt_def(id).all_fields().all(|field| {
67+
let field_type = tcx.type_of(field.did).instantiate_identity();
68+
// skip fields of PhantomData,
69+
// cause it's a common way to check things like well-formedness
70+
if field_type.is_phantom_data() {
71+
return true;
72+
}
73+
74+
field.vis.is_public()
75+
})
7676
}
7777

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

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

+2-2
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

+13-3
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
|
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() {}
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)