Rollup merge of #128104 - mu001999-contrib:fix/128053, r=petrochenkov
Not lint pub structs without pub constructors intentionally Fixes #128053
This commit is contained in:
commit
91b18a058c
@ -73,24 +73,26 @@ fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: LocalDefId) -> bool {
|
fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: LocalDefId) -> bool {
|
||||||
// treat PhantomData and positional ZST as public,
|
let adt_def = tcx.adt_def(id);
|
||||||
// we don't want to lint types which only have them,
|
|
||||||
// cause it's a common way to use such types to check things like well-formedness
|
// skip types contain fields of unit and never type,
|
||||||
tcx.adt_def(id).all_fields().all(|field| {
|
// it's usually intentional to make the type not constructible
|
||||||
|
let not_require_constructor = adt_def.all_fields().any(|field| {
|
||||||
let field_type = tcx.type_of(field.did).instantiate_identity();
|
let field_type = tcx.type_of(field.did).instantiate_identity();
|
||||||
if field_type.is_phantom_data() {
|
field_type.is_unit() || field_type.is_never()
|
||||||
return true;
|
});
|
||||||
}
|
|
||||||
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
|
not_require_constructor
|
||||||
if is_positional
|
|| adt_def.all_fields().all(|field| {
|
||||||
&& tcx
|
let field_type = tcx.type_of(field.did).instantiate_identity();
|
||||||
.layout_of(tcx.param_env(field.did).and(field_type))
|
// skip fields of PhantomData,
|
||||||
.map_or(true, |layout| layout.is_zst())
|
// cause it's a common way to check things like well-formedness
|
||||||
{
|
if field_type.is_phantom_data() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
field.vis.is_public()
|
|
||||||
})
|
field.vis.is_public()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check struct and its fields are public or not,
|
/// check struct and its fields are public or not,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#![forbid(dead_code)]
|
#![forbid(dead_code)]
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Whatever { //~ ERROR struct `Whatever` is never constructed
|
pub struct Whatever {
|
||||||
pub field0: (),
|
pub field0: (),
|
||||||
field1: (),
|
field1: (), //~ ERROR fields `field1`, `field2`, `field3`, and `field4` are never read
|
||||||
field2: (),
|
field2: (),
|
||||||
field3: (),
|
field3: (),
|
||||||
field4: (),
|
field4: (),
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
error: struct `Whatever` is never constructed
|
error: fields `field1`, `field2`, `field3`, and `field4` are never read
|
||||||
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:4:12
|
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:6:5
|
||||||
|
|
|
|
||||||
LL | pub struct Whatever {
|
LL | pub struct Whatever {
|
||||||
| ^^^^^^^^
|
| -------- fields in this struct
|
||||||
|
LL | pub field0: (),
|
||||||
|
LL | field1: (),
|
||||||
|
| ^^^^^^
|
||||||
|
LL | field2: (),
|
||||||
|
| ^^^^^^
|
||||||
|
LL | field3: (),
|
||||||
|
| ^^^^^^
|
||||||
|
LL | field4: (),
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
|
= note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:1:11
|
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:1:11
|
||||||
|
|
|
|
||||||
|
35
tests/ui/lint/dead-code/unconstructible-pub-struct.rs
Normal file
35
tests/ui/lint/dead-code/unconstructible-pub-struct.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#![feature(never_type)]
|
||||||
|
#![deny(dead_code)]
|
||||||
|
|
||||||
|
pub struct T1(!);
|
||||||
|
pub struct T2(());
|
||||||
|
pub struct T3<X>(std::marker::PhantomData<X>);
|
||||||
|
|
||||||
|
pub struct T4 {
|
||||||
|
_x: !,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct T5<X> {
|
||||||
|
_x: !,
|
||||||
|
_y: X,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct T6 {
|
||||||
|
_x: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct T7<X> {
|
||||||
|
_x: (),
|
||||||
|
_y: X,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct T8<X> {
|
||||||
|
_x: std::marker::PhantomData<X>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct T9<X> { //~ ERROR struct `T9` is never constructed
|
||||||
|
_x: std::marker::PhantomData<X>,
|
||||||
|
_y: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
tests/ui/lint/dead-code/unconstructible-pub-struct.stderr
Normal file
14
tests/ui/lint/dead-code/unconstructible-pub-struct.stderr
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
error: struct `T9` is never constructed
|
||||||
|
--> $DIR/unconstructible-pub-struct.rs:30:12
|
||||||
|
|
|
||||||
|
LL | pub struct T9<X> {
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/unconstructible-pub-struct.rs:2:9
|
||||||
|
|
|
||||||
|
LL | #![deny(dead_code)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
Loading…
Reference in New Issue
Block a user